false
true
0

Contract Address Details

0x1d2500341B5c8223D02AE0a957cBB384Ac21Ab20

Contract Name
LimitBook
Creator
0x41fc09–45f742 at 0x77df9e–7597db
Balance
0 tPLS
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
25393091
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
LimitBook




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




EVM Version




Verified at
2026-09-02T15:48:47.549747Z

Constructor Arguments

00000000000000000000000003db6f13bc4ef65cfa690d2e836c3affd7d476a10000000000000000000000009ed4801d002fd7b694ef9fc46cc2caa58f80203c000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000008ac7230489e80000

Arg [0] (address) : 0x03db6f13bc4ef65cfa690d2e836c3affd7d476a1
Arg [1] (address) : 0x9ed4801d002fd7b694ef9fc46cc2caa58f80203c
Arg [2] (uint16) : 10
Arg [3] (uint96) : 10000000000000000000

              

src/LimitBook.sol

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

interface IERC20B {
    function transfer(address to, uint256 amt) external returns (bool);
    function transferFrom(address from, address to, uint256 amt) external returns (bool);
    function approve(address spender, uint256 amt) external returns (bool);
    function balanceOf(address who) external view returns (uint256);
}

interface IFamilyFactoryB {
    function isFamily(address token) external view returns (bool);
}

interface IFamilyLaunchB {
    function paired() external view returns (address);
    function buy(uint256 pairedIn, uint256 minOut, address recipient) external returns (uint256 out);
    function sell(uint256 tokensIn, uint256 minOut) external returns (uint256 payout);
    function quoteBuy(uint256 pairedIn) external view returns (uint256);
    function quoteSell(uint256 tokensIn) external view returns (uint256);
    function inSnipeWindow() external view returns (bool);
    function dividendsOf(address who) external view returns (uint256);
    function claimDividends() external returns (uint256);
}

/// @title LimitBook — resting limit orders for pulsefam pools
/// @notice An escrow + trigger, not an exchange. Anyone may call execute();
///         the call succeeds only if the pool can fill the ENTIRE order at an
///         average price at least as good as the owner's limit, and the
///         executor earns a small paired-asset bounty for pulling the trigger.
///         The single minOut passed into buy()/sell() is simultaneously the
///         trigger condition and the slippage guarantee — no oracle, no price
///         feed, no keeper with keys. Constructor parameters are immutable;
///         there is no owner, no pause, no upgrade — pulsefam house rules.
contract LimitBook {
    enum Side { BuyLimit, SellLimit }

    struct Order {
        address owner;     // who placed it, who can cancel it, who receives proceeds
        address token;     // FamilyLaunch — gated by factory.isFamily at placement
        Side    side;
        uint96  amount;    // BuyLimit: paired in escrow · SellLimit: tokens in escrow
        uint128 priceX18;  // paired wei per 1e18 token wei
        uint40  expiry;    // unix seconds; 0 = good-til-cancelled
        bool    open;
    }

    // -------------------------------------------------------------- immutable
    IFamilyFactoryB public immutable factory;
    address public immutable sink;            // MoonxSink — forfeited dividends land here
    uint16 public immutable executorFeeBps;   // bounty, always paid in the paired asset
    uint96 public immutable minOrderPaired;   // dust orders are unexecutable-forever gas griefs

    // ---------------------------------------------------------------- storage
    Order[] public orders;                         // orderId = array index
    mapping(address => uint256[]) public ordersOf; // owner => ids (append-only; UI filters open)

    uint256 private _lock = 1;

    event OrderPlaced(
        uint256 indexed id, address indexed owner, address indexed token,
        Side side, uint96 amount, uint128 priceX18, uint40 expiry
    );
    event OrderCancelled(uint256 indexed id, address indexed owner);
    event OrderExecuted(
        uint256 indexed id, address indexed token, address indexed executor,
        uint256 out, uint256 bounty
    );
    event DividendsSkimmed(address indexed token, uint256 amount);

    /// @dev The book custodies every open order's escrow in one balance; a
    ///      hooked asset must find the book closed for business mid-operation,
    ///      exactly as FamilyLaunch closes its side (PF-1).
    modifier lock() {
        require(_lock == 1, "reentrancy");
        _lock = 2;
        _;
        _lock = 1;
    }

    constructor(address factory_, address sink_, uint16 executorFeeBps_, uint96 minOrderPaired_) {
        require(factory_ != address(0) && sink_ != address(0), "bad params");
        // A bounty at or above 100% would consume the whole escrow; anything
        // sane is single-digit bps, but the constructor only enforces the
        // mathematical floor — the deployer's number is public and immutable.
        require(executorFeeBps_ < 10000, "fee bps");
        factory = IFamilyFactoryB(factory_);
        sink = sink_;
        executorFeeBps = executorFeeBps_;
        minOrderPaired = minOrderPaired_;
    }

    // ----------------------------------------------------------------- views
    function orderCount() external view returns (uint256) {
        return orders.length;
    }

    function ordersOfCount(address who) external view returns (uint256) {
        return ordersOf[who].length;
    }

    /// @notice Keeper convenience: same trigger math as execute(), via the
    ///         pool's quote views, without state change. Conservative on one
    ///         edge: a sell quoted inside the snipe window reports false even
    ///         though an absurdly low limit could technically clear — the
    ///         execute() path stays the single source of truth.
    function executable(uint256 id) external view returns (bool ok, uint256 quoteOut) {
        Order storage o = orders[id];
        if (!o.open) return (false, 0);
        if (o.expiry != 0 && block.timestamp >= o.expiry) return (false, 0);
        IFamilyLaunchB fam = IFamilyLaunchB(o.token);
        if (o.side == Side.BuyLimit) {
            uint256 netIn = uint256(o.amount) - (uint256(o.amount) * executorFeeBps) / 10000;
            quoteOut = fam.quoteBuy(netIn);
            ok = quoteOut > 0 && quoteOut >= (netIn * 1e18) / o.priceX18;
        } else {
            uint256 minOwnerOut = (uint256(o.amount) * o.priceX18) / 1e18;
            uint256 bounty = (minOwnerOut * executorFeeBps) / 10000;
            quoteOut = fam.quoteSell(o.amount);
            ok = !fam.inSnipeWindow() && quoteOut >= minOwnerOut + bounty;
        }
    }

    // ----------------------------------------------------------------- place
    /// @notice Escrow now, execute later. BuyLimit escrows the token's paired
    ///         asset; SellLimit escrows the tokens themselves. The paired
    ///         asset is always read from the token (immutable there), never
    ///         stored — one fewer copy to keep honest.
    function place(
        address token, Side side, uint96 amount, uint128 priceX18, uint40 expiry
    ) external lock returns (uint256 id) {
        // isFamily restricts tokens to factory-deployed bytecode — the first
        // wall; balance-delta checks below are the second (defense in depth).
        require(factory.isFamily(token), "not family");
        require(priceX18 > 0, "zero price");
        require(expiry == 0 || expiry > block.timestamp, "past expiry");
        // Min size is paired-denominated on both sides: a sell's escrow is
        // valued at its own limit price — the number the owner insists on.
        uint256 pairedValue = side == Side.BuyLimit
            ? uint256(amount)
            : (uint256(amount) * priceX18) / 1e18;
        require(pairedValue >= minOrderPaired, "below min");

        IERC20B asset = side == Side.BuyLimit
            ? IERC20B(IFamilyLaunchB(token).paired())
            : IERC20B(token);
        // PF-3 keeps fee-on-transfer assets out; the delta check keeps the
        // escrow accounting honest even if that assumption ever slips.
        uint256 balBefore = asset.balanceOf(address(this));
        require(asset.transferFrom(msg.sender, address(this), amount), "escrow pull");
        require(asset.balanceOf(address(this)) - balBefore == amount, "escrow delta");

        id = orders.length;
        orders.push(Order(msg.sender, token, side, amount, priceX18, expiry, true));
        ordersOf[msg.sender].push(id);
        emit OrderPlaced(id, msg.sender, token, side, amount, priceX18, expiry);
    }

    // ---------------------------------------------------------------- cancel
    /// @notice Owner only, any time while open — expired orders stay
    ///         cancellable forever. Full escrow back, no fee on cancel.
    function cancel(uint256 id) external lock {
        Order storage o = orders[id];
        require(o.open, "closed");
        require(msg.sender == o.owner, "not owner");
        o.open = false; // effects before the refund leaves
        IERC20B asset = o.side == Side.BuyLimit
            ? IERC20B(IFamilyLaunchB(o.token).paired())
            : IERC20B(o.token);
        require(asset.transfer(o.owner, o.amount), "refund");
        emit OrderCancelled(id, o.owner);
    }

    // --------------------------------------------------------------- execute
    /// @notice Permissionless. The limit is enforced by the POOL: the minOut
    ///         computed here is passed straight into buy()/sell(), so a fill
    ///         worse than the owner's limit is not a griefable edge case — it
    ///         is a revert. Limit math runs on the NET amount, so the bounty
    ///         can never push a fill below the stated limit.
    function execute(uint256 id) external lock returns (uint256 out) {
        Order storage o = orders[id];
        require(o.open, "closed");
        require(o.expiry == 0 || block.timestamp < o.expiry, "expired");
        o.open = false; // closed BEFORE any external call — CEI

        IFamilyLaunchB fam = IFamilyLaunchB(o.token);
        IERC20B pairedAsset = IERC20B(fam.paired());
        uint256 bounty;

        if (o.side == Side.BuyLimit) {
            bounty = (uint256(o.amount) * executorFeeBps) / 10000;
            uint256 netIn = uint256(o.amount) - bounty;
            uint256 minOut = (netIn * 1e18) / o.priceX18;
            // Exact allowance granted immediately before the buy and spent in
            // full by it — a hostile token's reach ends at this order's escrow.
            uint256 balBefore = pairedAsset.balanceOf(address(this));
            require(pairedAsset.approve(o.token, netIn), "approve");
            // recipient = owner: the book never holds family tokens for buys.
            out = fam.buy(netIn, minOut, o.owner);
            require(balBefore - pairedAsset.balanceOf(address(this)) == netIn, "spend delta");
        } else {
            uint256 minOwnerOut = (uint256(o.amount) * o.priceX18) / 1e18;
            bounty = (minOwnerOut * executorFeeBps) / 10000;
            // The pool must clear limit + bounty so the OWNER nets the limit;
            // any surplus above the floor is the owner's, not the executor's.
            uint256 balBefore = pairedAsset.balanceOf(address(this));
            uint256 payout = fam.sell(o.amount, minOwnerOut + bounty);
            require(pairedAsset.balanceOf(address(this)) - balBefore == payout, "payout delta");
            out = payout - bounty;
            require(pairedAsset.transfer(o.owner, out), "proceeds");
        }
        if (bounty > 0) require(pairedAsset.transfer(msg.sender, bounty), "bounty");
        emit OrderExecuted(id, o.token, msg.sender, out, bounty);
    }

    // ------------------------------------------------------------- dividends
    /// @notice Resting sell escrows make the book a holder on holder-mode
    ///         tokens; per-order attribution would mean re-implementing the
    ///         magnified-dividend maths here. v1 policy: forfeit-to-burn —
    ///         permissionless skim into the MoonxSink, where the 80/20 applies.
    /// @dev Dividends arrive in the paired asset — the same asset buy escrows
    ///      sit in — so the skim forwards EXACTLY the balance delta of the
    ///      claim call and can never touch an order's escrow.
    function skimDividends(address token) external lock {
        require(factory.isFamily(token), "not family");
        IFamilyLaunchB fam = IFamilyLaunchB(token);
        IERC20B pairedAsset = IERC20B(fam.paired());
        uint256 balBefore = pairedAsset.balanceOf(address(this));
        fam.claimDividends(); // reverts "nothing" when zero accrued
        uint256 got = pairedAsset.balanceOf(address(this)) - balBefore;
        require(pairedAsset.transfer(sink, got), "sink push");
        emit DividendsSkimmed(token, got);
    }
}
        

Compiler Settings

{"viaIR":true,"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"],"":["ast"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{},"evmVersion":"paris"}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"factory_","internalType":"address"},{"type":"address","name":"sink_","internalType":"address"},{"type":"uint16","name":"executorFeeBps_","internalType":"uint16"},{"type":"uint96","name":"minOrderPaired_","internalType":"uint96"}]},{"type":"event","name":"DividendsSkimmed","inputs":[{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OrderCancelled","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":true},{"type":"address","name":"owner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OrderExecuted","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":true},{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"address","name":"executor","internalType":"address","indexed":true},{"type":"uint256","name":"out","internalType":"uint256","indexed":false},{"type":"uint256","name":"bounty","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OrderPlaced","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":true},{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"uint8","name":"side","internalType":"enum LimitBook.Side","indexed":false},{"type":"uint96","name":"amount","internalType":"uint96","indexed":false},{"type":"uint128","name":"priceX18","internalType":"uint128","indexed":false},{"type":"uint40","name":"expiry","internalType":"uint40","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cancel","inputs":[{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"ok","internalType":"bool"},{"type":"uint256","name":"quoteOut","internalType":"uint256"}],"name":"executable","inputs":[{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"out","internalType":"uint256"}],"name":"execute","inputs":[{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"executorFeeBps","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IFamilyFactoryB"}],"name":"factory","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint96","name":"","internalType":"uint96"}],"name":"minOrderPaired","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"orderCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"token","internalType":"address"},{"type":"uint8","name":"side","internalType":"enum LimitBook.Side"},{"type":"uint96","name":"amount","internalType":"uint96"},{"type":"uint128","name":"priceX18","internalType":"uint128"},{"type":"uint40","name":"expiry","internalType":"uint40"},{"type":"bool","name":"open","internalType":"bool"}],"name":"orders","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"ordersOf","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"ordersOfCount","inputs":[{"type":"address","name":"who","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"id","internalType":"uint256"}],"name":"place","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint8","name":"side","internalType":"enum LimitBook.Side"},{"type":"uint96","name":"amount","internalType":"uint96"},{"type":"uint128","name":"priceX18","internalType":"uint128"},{"type":"uint40","name":"expiry","internalType":"uint40"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"sink","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"skimDividends","inputs":[{"type":"address","name":"token","internalType":"address"}]}]
              

Contract Creation Code

0x610100346200019957601f62001ccb38819003918201601f19168301916001600160401b038311848410176200019e5780849260809460405283398101031262000199576200004e81620001b4565b6200005c60208301620001b4565b60408301519161ffff831693848403620001995760600151936001600160601b0385168503620001995760016002556001600160a01b039182169182151590816200018c575b50156200015a5761271011156200012b5760805260a05260c05260e052604051611b019081620001ca823960805181818161093701528181610b06015261104f015260a05181818161089a0152610bf6015260c0518181816101790152818161058e01528181610f92015281816118b801526119cc015260e0518181816109ec01526110c80152f35b60405162461bcd60e51b81526020600482015260076024820152666665652062707360c81b6044820152606490fd5b60405162461bcd60e51b815260206004820152600a60248201526962616420706172616d7360b01b6044820152606490fd5b90508316151538620000a2565b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203620001995756fe6080604052600436101561001257600080fd5b60003560e01c80630aace5a314610fb65780631294a32614610f775780632453ffa814610f5957806340e58ee514610d8d5780635c77063c14610ab1578063a85c38ef14610a10578063b767f825146109cc578063bc38c59714610992578063c219a78514610966578063c45a015514610921578063c639f9f2146108c9578063c74e820e146108845763fe0d94c1146100ab57600080fd5b3461047a57602036600319011261047a576100ca6001600254146116f1565b600280556100d9600435611669565b506003810180546100ef60ff8260281c166117fc565b64ffffffffff8116801590811561087a575b501561084b5765ff000000000019169055600181015460405163cf88033160e01b81526020816004816001600160a01b0386165afa90811561040d5760009161081c575b5060ff8260a01c16600281101561080657610551576002830154906001600160601b038216916101a761271061019f61ffff7f0000000000000000000000000000000000000000000000000000000000000000168661179d565b0480946117ef565b9081670de0b6b3a7640000810204670de0b6b3a7640000148215171561053b576001600160801b036101e79160601c16670de0b6b3a764000083026117b0565b6040516370a0823160e01b815230600482015294906020866024816001600160a01b0388165afa95861561040d57600096610507575b50600187015460405163095ea7b360e01b81526001600160a01b039091166004820152602481018490526020818060448101038160006001600160a01b038a165af190811561040d576000916104e8575b50156104b95786546040516359a87bc160e01b81526004810185905260248101929092526001600160a01b039081166044830152909160209183916064918391600091165af190811561040d57600091610487575b506040516370a0823160e01b815230600482015290946020826024816001600160a01b0388165afa90811561040d5760009161044c575b61030492506117ef565b03610419575b81610362575b506020926001808060a01b0391015416604051918383528483015233917fd7a87d0519b9db74efbaf0a5663d18f1aafacf8b1c4fc1c962d727414662a092604060043592a46001600255604051908152f35b60405163a9059cbb60e01b81523360048201526024810183905290602090829060449082906000906001600160a01b03165af190811561040d576000916103de575b50156103b05738610310565b60405162461bcd60e51b8152602060048201526006602482015265626f756e747960d01b6044820152606490fd5b610400915060203d602011610406575b6103f8818361172a565b81019061174c565b386103a4565b503d6103ee565b6040513d6000823e3d90fd5b60405162461bcd60e51b815260206004820152600b60248201526a7370656e642064656c746160a81b6044820152606490fd5b90506020823d60201161047f575b816104676020938361172a565b8101031261047a576103049151906102fa565b600080fd5b3d915061045a565b90506020813d6020116104b1575b816104a26020938361172a565b8101031261047a5751386102c3565b3d9150610495565b60405162461bcd60e51b8152602060048201526007602482015266617070726f766560c81b6044820152606490fd5b610501915060203d602011610406576103f8818361172a565b3861026e565b9095506020813d602011610533575b816105236020938361172a565b8101031261047a5751943861021d565b3d9150610516565b634e487b7160e01b600052601160045260246000fd5b90600283015490670de0b6b3a76400006105816001600160801b036001600160601b0385169460601c168461179d565b04916127106105b461ffff7f0000000000000000000000000000000000000000000000000000000000000000168561179d565b6040516370a0823160e01b808252306004830152929091049491926020826024816001600160a01b038b165afa91821561040d5786906000936107ce575b5061060260449160209495611831565b60405163d79875eb60e01b815260048101939093526024830152909485919082906000906001600160a01b03165af192831561040d5760009361079a575b506040519182523060048301526020826024816001600160a01b0389165afa801561040d578392600091610761575b509061067a916117ef565b0361072d5781610689916117ef565b835460405163a9059cbb60e01b81526001600160a01b039091166004820152602481018290529092906020818060448101038160006001600160a01b0387165af190811561040d5760009161070e575b5061030a5760405162461bcd60e51b815260206004820152600860248201526770726f636565647360c01b6044820152606490fd5b610727915060203d602011610406576103f8818361172a565b386106d9565b60405162461bcd60e51b815260206004820152600c60248201526b7061796f75742064656c746160a01b6044820152606490fd5b919250506020813d602011610792575b8161077e6020938361172a565b8101031261047a575182919061067a61066f565b3d9150610771565b9092506020813d6020116107c6575b816107b66020938361172a565b8101031261047a57519138610640565b3d91506107a9565b9250506020823d6020116107fe575b816107ea6020938361172a565b8101031261047a57905190856106026105f2565b3d91506107dd565b634e487b7160e01b600052602160045260246000fd5b61083e915060203d602011610844575b610836818361172a565b8101906117d0565b38610145565b503d61082c565b60405162461bcd60e51b8152602060048201526007602482015266195e1c1a5c995960ca1b6044820152606490fd5b9050421038610101565b3461047a57600036600319011261047a576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461047a57604036600319011261047a576108e2611653565b6001600160a01b031660009081526001602052604090208054602435919082101561047a57602091610913916116c3565b90546040519160031b1c8152f35b3461047a57600036600319011261047a576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461047a57602036600319011261047a57604061098460043561183e565b825191151582526020820152f35b3461047a57602036600319011261047a576001600160a01b036109b3611653565b1660005260016020526020604060002054604051908152f35b3461047a57600036600319011261047a5760206040516001600160601b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461047a57602036600319011261047a5760043560005481101561047a57610a3960e091611669565b5060ff60018060a01b036001600160801b038184541693610a7f600182015460036002840154930154946040519788528116602088015285604088019160a01c166116b6565b6001600160601b038116606086015260601c16608084015264ffffffffff811660a084015260281c16151560c0820152f35b3461047a5760208060031936011261047a57610acb611653565b90610ada6001600254146116f1565b6002805560405163f8e5695760e01b81526001600160a01b0392831660048201819052929082816024817f000000000000000000000000000000000000000000000000000000000000000086165afa801561040d57610b4191600091610d70575b50611764565b60405163cf88033160e01b81528281600481875afa90811561040d57600091610d53575b50166040516370a0823160e01b908181523060048201528381602481865afa90811561040d57600091610d26575b5060405163033401c760e51b8152848160048160008a5af190811561040d578591610cfd575b50506040519182523060048301528382602481865afa801561040d57600090610cce575b610be792506117ef565b60405163a9059cbb60e01b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031660048201526024810182905290918390829060449082906000905af190811561040d57600091610cb1575b5015610c8057907f9ffa1d4203b06d05cd96ec12eb8f0fd59080e9391dfdf4a463ff4437a292725191604051908152a26001600255005b60405162461bcd60e51b81526004810183905260096024820152680e6d2dcd640e0eae6d60bb1b6044820152606490fd5b610cc89150833d8511610406576103f8818361172a565b84610c49565b508382813d8311610cf6575b610ce4818361172a565b8101031261047a57610be79151610bdd565b503d610cda565b813d8311610d1f575b610d10818361172a565b8101031261047a578386610bb9565b503d610d06565b90508381813d8311610d4c575b610d3d818361172a565b8101031261047a575185610b93565b503d610d33565b610d6a9150833d851161084457610836818361172a565b84610b65565b610d879150843d8611610406576103f8818361172a565b85610b3b565b3461047a5760208060031936011261047a57600435600290610db260018354146116f1565b818055610dbe81611669565b5060038101908154610dd560ff8260281c166117fc565b81546001600160a01b03939084169133839003610f285765ff000000000019169055600182015460ff8160a01c16868110156108065784918891610f1e5760046040518094819363cf88033160e01b8352165afa90811561040d5787918591600091610f01575b5016915b60446001600160601b03888601541691600087604051968795869463a9059cbb60e01b865260048601526024850152165af190811561040d57600091610ee4575b5015610eb657600194505416907fc0362da6f2ff36b382b34aec0814f6b3cdf89f5ef282a1d1f114d0c0b036d596600080a355005b60405162461bcd60e51b81526004810186905260066024820152651c99599d5b9960d21b6044820152606490fd5b610efb9150863d8811610406576103f8818361172a565b86610e81565b610f189150833d851161084457610836818361172a565b89610e3c565b9190911691610e40565b60405162461bcd60e51b81526004810189905260096024820152683737ba1037bbb732b960b91b6044820152606490fd5b3461047a57600036600319011261047a576020600054604051908152f35b3461047a57600036600319011261047a57602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461047a5760a036600319011261047a57610fcf611653565b6002602435101561047a57604435906001600160601b038216820361047a57606435916001600160801b038316830361047a576084359164ffffffffff8316830361047a576110226001600254146116f1565b6002805560405163f8e5695760e01b81526001600160a01b038281166004830152602090829060249082907f0000000000000000000000000000000000000000000000000000000000000000165afa801561040d57611088916000916116345750611764565b6001600160801b038416156116025764ffffffffff83161580156115f2575b156115bf57602435611594576001600160601b0382165b6001600160601b037f00000000000000000000000000000000000000000000000000000000000000001611611563576024356115545760405163cf88033160e01b81526020816004816001600160a01b0386165afa90811561040d57600091611535575b506001600160a01b03165b6040516370a0823160e01b81523060048201526020816024816001600160a01b0386165afa90811561040d57600091611503575b506040516323b872dd60e01b81523360048201523060248201526001600160601b038516604482015260208160648160006001600160a01b0388165af190811561040d576000916114e4575b50156114b1576040516370a0823160e01b815230600482015291602090839060249082906001600160a01b03165afa91821561040d5760009261147b575b50611200906001600160601b038516926117ef565b0361144757600054926040518060e081011067ffffffffffffffff60e08301111761141b5760e0810160409081523382526001600160a01b0384166020830152602435908201526001600160601b03841660608201526001600160801b038616608082015264ffffffffff821660a0820152600160c0820152600160401b85101561141b576001850160005561129585611669565b61143157815181546001600160a01b0319166001600160a01b03918216178255602083015160018301546040850151939290911660028410156108065760039360ff60a01b9060a01b16916affffffffffffffffffffff60a81b1617176001820155600281016001600160601b036060850151168154906001600160801b0360601b608087015160601b169163ffffffff60e01b1617179055019064ffffffffff60a08201511665ff000000000060c08454930151151560281b169165ffffffffffff1916171790553360005260016020526040600020908154600160401b81101561141b5760209661139c8264ffffffffff9560016001600160801b03950181556116c3565b81549060031b9089821b91600019901b19161790556001600160601b03604051966113c9886024356116b6565b16868901521660408501521660608301526001600160a01b031690339083907f27d0ce60b30e7976ccdc89c73d93a6540dc16fca1882f51aaaabf47b466ec4f690608090a46001600255604051908152f35b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052600060045260246000fd5b60405162461bcd60e51b815260206004820152600c60248201526b657363726f772064656c746160a01b6044820152606490fd5b9091506020813d6020116114a9575b816114976020938361172a565b8101031261047a5751906112006111eb565b3d915061148a565b60405162461bcd60e51b815260206004820152600b60248201526a195cd8dc9bddc81c1d5b1b60aa1b6044820152606490fd5b6114fd915060203d602011610406576103f8818361172a565b876111ad565b90506020813d60201161152d575b8161151e6020938361172a565b8101031261047a575186611161565b3d9150611511565b61154e915060203d60201161084457610836818361172a565b85611122565b6001600160a01b03811661112d565b60405162461bcd60e51b81526020600482015260096024820152683132b637bb9036b4b760b91b6044820152606490fd5b670de0b6b3a76400006115b96001600160801b0386166001600160601b03851661179d565b046110be565b60405162461bcd60e51b815260206004820152600b60248201526a706173742065787069727960a81b6044820152606490fd5b504264ffffffffff8416116110a7565b60405162461bcd60e51b815260206004820152600a6024820152697a65726f20707269636560b01b6044820152606490fd5b61164d915060203d602011610406576103f8818361172a565b86610b3b565b600435906001600160a01b038216820361047a57565b9060009182548110156116a25782805260021b7f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563019190565b634e487b7160e01b83526032600452602483fd5b9060028210156108065752565b80548210156116db5760005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b156116f857565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b90601f8019910116810190811067ffffffffffffffff82111761141b57604052565b9081602091031261047a5751801515810361047a5790565b1561176b57565b60405162461bcd60e51b815260206004820152600a6024820152696e6f742066616d696c7960b01b6044820152606490fd5b8181029291811591840414171561053b57565b81156117ba570490565b634e487b7160e01b600052601260045260246000fd5b9081602091031261047a57516001600160a01b038116810361047a5790565b9190820391821161053b57565b1561180357565b60405162461bcd60e51b815260206004820152600660248201526518db1bdcd95960d21b6044820152606490fd5b9190820180921161053b57565b61184790611669565b50600381015460ff8160281c1615611ac15764ffffffffff168015159081611ab6575b50611aad5760018101546001600160a01b0381169160a09190911c60ff169060028210156108065760029161199457015490602460206118e56001600160601b0385166127106118de61ffff7f0000000000000000000000000000000000000000000000000000000000000000168361179d565b04906117ef565b92604051928380926312face5360e21b82528660048301525afa90811561040d5760009161195f575b5080928115159283611921575b50505091565b90919250670de0b6b3a76400009081810291818304149015171561053b576001600160801b036119559260601c16906117b0565b111538808061191b565b906020823d60201161198c575b816119796020938361172a565b810103126119895750513861190e565b80fd5b3d915061196c565b0154670de0b6b3a76400006119bf6001600160801b036001600160601b0384169360601c168361179d565b04906127106119f261ffff7f0000000000000000000000000000000000000000000000000000000000000000168461179d565b0460405191632990643160e21b8352600483015260208083602481885afa92831561040d57600093611a7e575b506004818496604051928380926342103df160e11b82525afa91821561040d57600092611a61575b5050159283611a565750505091565b611955929350611831565b611a779250803d10610406576103f8818361172a565b3880611a47565b9080935081813d8311611aa6575b611a96818361172a565b8101031261047a57519138611a1f565b503d611a8c565b50600090600090565b90504210153861186a565b505060009060009056fea26469706673582212208a9a3c3b9c437b238d758ccdcb904f7ab04410cc8bb929ba4f63aecf7c01f42c64736f6c6343000818003300000000000000000000000003db6f13bc4ef65cfa690d2e836c3affd7d476a10000000000000000000000009ed4801d002fd7b694ef9fc46cc2caa58f80203c000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000008ac7230489e80000

Deployed ByteCode

0x6080604052600436101561001257600080fd5b60003560e01c80630aace5a314610fb65780631294a32614610f775780632453ffa814610f5957806340e58ee514610d8d5780635c77063c14610ab1578063a85c38ef14610a10578063b767f825146109cc578063bc38c59714610992578063c219a78514610966578063c45a015514610921578063c639f9f2146108c9578063c74e820e146108845763fe0d94c1146100ab57600080fd5b3461047a57602036600319011261047a576100ca6001600254146116f1565b600280556100d9600435611669565b506003810180546100ef60ff8260281c166117fc565b64ffffffffff8116801590811561087a575b501561084b5765ff000000000019169055600181015460405163cf88033160e01b81526020816004816001600160a01b0386165afa90811561040d5760009161081c575b5060ff8260a01c16600281101561080657610551576002830154906001600160601b038216916101a761271061019f61ffff7f000000000000000000000000000000000000000000000000000000000000000a168661179d565b0480946117ef565b9081670de0b6b3a7640000810204670de0b6b3a7640000148215171561053b576001600160801b036101e79160601c16670de0b6b3a764000083026117b0565b6040516370a0823160e01b815230600482015294906020866024816001600160a01b0388165afa95861561040d57600096610507575b50600187015460405163095ea7b360e01b81526001600160a01b039091166004820152602481018490526020818060448101038160006001600160a01b038a165af190811561040d576000916104e8575b50156104b95786546040516359a87bc160e01b81526004810185905260248101929092526001600160a01b039081166044830152909160209183916064918391600091165af190811561040d57600091610487575b506040516370a0823160e01b815230600482015290946020826024816001600160a01b0388165afa90811561040d5760009161044c575b61030492506117ef565b03610419575b81610362575b506020926001808060a01b0391015416604051918383528483015233917fd7a87d0519b9db74efbaf0a5663d18f1aafacf8b1c4fc1c962d727414662a092604060043592a46001600255604051908152f35b60405163a9059cbb60e01b81523360048201526024810183905290602090829060449082906000906001600160a01b03165af190811561040d576000916103de575b50156103b05738610310565b60405162461bcd60e51b8152602060048201526006602482015265626f756e747960d01b6044820152606490fd5b610400915060203d602011610406575b6103f8818361172a565b81019061174c565b386103a4565b503d6103ee565b6040513d6000823e3d90fd5b60405162461bcd60e51b815260206004820152600b60248201526a7370656e642064656c746160a81b6044820152606490fd5b90506020823d60201161047f575b816104676020938361172a565b8101031261047a576103049151906102fa565b600080fd5b3d915061045a565b90506020813d6020116104b1575b816104a26020938361172a565b8101031261047a5751386102c3565b3d9150610495565b60405162461bcd60e51b8152602060048201526007602482015266617070726f766560c81b6044820152606490fd5b610501915060203d602011610406576103f8818361172a565b3861026e565b9095506020813d602011610533575b816105236020938361172a565b8101031261047a5751943861021d565b3d9150610516565b634e487b7160e01b600052601160045260246000fd5b90600283015490670de0b6b3a76400006105816001600160801b036001600160601b0385169460601c168461179d565b04916127106105b461ffff7f000000000000000000000000000000000000000000000000000000000000000a168561179d565b6040516370a0823160e01b808252306004830152929091049491926020826024816001600160a01b038b165afa91821561040d5786906000936107ce575b5061060260449160209495611831565b60405163d79875eb60e01b815260048101939093526024830152909485919082906000906001600160a01b03165af192831561040d5760009361079a575b506040519182523060048301526020826024816001600160a01b0389165afa801561040d578392600091610761575b509061067a916117ef565b0361072d5781610689916117ef565b835460405163a9059cbb60e01b81526001600160a01b039091166004820152602481018290529092906020818060448101038160006001600160a01b0387165af190811561040d5760009161070e575b5061030a5760405162461bcd60e51b815260206004820152600860248201526770726f636565647360c01b6044820152606490fd5b610727915060203d602011610406576103f8818361172a565b386106d9565b60405162461bcd60e51b815260206004820152600c60248201526b7061796f75742064656c746160a01b6044820152606490fd5b919250506020813d602011610792575b8161077e6020938361172a565b8101031261047a575182919061067a61066f565b3d9150610771565b9092506020813d6020116107c6575b816107b66020938361172a565b8101031261047a57519138610640565b3d91506107a9565b9250506020823d6020116107fe575b816107ea6020938361172a565b8101031261047a57905190856106026105f2565b3d91506107dd565b634e487b7160e01b600052602160045260246000fd5b61083e915060203d602011610844575b610836818361172a565b8101906117d0565b38610145565b503d61082c565b60405162461bcd60e51b8152602060048201526007602482015266195e1c1a5c995960ca1b6044820152606490fd5b9050421038610101565b3461047a57600036600319011261047a576040517f0000000000000000000000009ed4801d002fd7b694ef9fc46cc2caa58f80203c6001600160a01b03168152602090f35b3461047a57604036600319011261047a576108e2611653565b6001600160a01b031660009081526001602052604090208054602435919082101561047a57602091610913916116c3565b90546040519160031b1c8152f35b3461047a57600036600319011261047a576040517f00000000000000000000000003db6f13bc4ef65cfa690d2e836c3affd7d476a16001600160a01b03168152602090f35b3461047a57602036600319011261047a57604061098460043561183e565b825191151582526020820152f35b3461047a57602036600319011261047a576001600160a01b036109b3611653565b1660005260016020526020604060002054604051908152f35b3461047a57600036600319011261047a5760206040516001600160601b037f0000000000000000000000000000000000000000000000008ac7230489e80000168152f35b3461047a57602036600319011261047a5760043560005481101561047a57610a3960e091611669565b5060ff60018060a01b036001600160801b038184541693610a7f600182015460036002840154930154946040519788528116602088015285604088019160a01c166116b6565b6001600160601b038116606086015260601c16608084015264ffffffffff811660a084015260281c16151560c0820152f35b3461047a5760208060031936011261047a57610acb611653565b90610ada6001600254146116f1565b6002805560405163f8e5695760e01b81526001600160a01b0392831660048201819052929082816024817f00000000000000000000000003db6f13bc4ef65cfa690d2e836c3affd7d476a186165afa801561040d57610b4191600091610d70575b50611764565b60405163cf88033160e01b81528281600481875afa90811561040d57600091610d53575b50166040516370a0823160e01b908181523060048201528381602481865afa90811561040d57600091610d26575b5060405163033401c760e51b8152848160048160008a5af190811561040d578591610cfd575b50506040519182523060048301528382602481865afa801561040d57600090610cce575b610be792506117ef565b60405163a9059cbb60e01b81527f0000000000000000000000009ed4801d002fd7b694ef9fc46cc2caa58f80203c6001600160a01b031660048201526024810182905290918390829060449082906000905af190811561040d57600091610cb1575b5015610c8057907f9ffa1d4203b06d05cd96ec12eb8f0fd59080e9391dfdf4a463ff4437a292725191604051908152a26001600255005b60405162461bcd60e51b81526004810183905260096024820152680e6d2dcd640e0eae6d60bb1b6044820152606490fd5b610cc89150833d8511610406576103f8818361172a565b84610c49565b508382813d8311610cf6575b610ce4818361172a565b8101031261047a57610be79151610bdd565b503d610cda565b813d8311610d1f575b610d10818361172a565b8101031261047a578386610bb9565b503d610d06565b90508381813d8311610d4c575b610d3d818361172a565b8101031261047a575185610b93565b503d610d33565b610d6a9150833d851161084457610836818361172a565b84610b65565b610d879150843d8611610406576103f8818361172a565b85610b3b565b3461047a5760208060031936011261047a57600435600290610db260018354146116f1565b818055610dbe81611669565b5060038101908154610dd560ff8260281c166117fc565b81546001600160a01b03939084169133839003610f285765ff000000000019169055600182015460ff8160a01c16868110156108065784918891610f1e5760046040518094819363cf88033160e01b8352165afa90811561040d5787918591600091610f01575b5016915b60446001600160601b03888601541691600087604051968795869463a9059cbb60e01b865260048601526024850152165af190811561040d57600091610ee4575b5015610eb657600194505416907fc0362da6f2ff36b382b34aec0814f6b3cdf89f5ef282a1d1f114d0c0b036d596600080a355005b60405162461bcd60e51b81526004810186905260066024820152651c99599d5b9960d21b6044820152606490fd5b610efb9150863d8811610406576103f8818361172a565b86610e81565b610f189150833d851161084457610836818361172a565b89610e3c565b9190911691610e40565b60405162461bcd60e51b81526004810189905260096024820152683737ba1037bbb732b960b91b6044820152606490fd5b3461047a57600036600319011261047a576020600054604051908152f35b3461047a57600036600319011261047a57602060405161ffff7f000000000000000000000000000000000000000000000000000000000000000a168152f35b3461047a5760a036600319011261047a57610fcf611653565b6002602435101561047a57604435906001600160601b038216820361047a57606435916001600160801b038316830361047a576084359164ffffffffff8316830361047a576110226001600254146116f1565b6002805560405163f8e5695760e01b81526001600160a01b038281166004830152602090829060249082907f00000000000000000000000003db6f13bc4ef65cfa690d2e836c3affd7d476a1165afa801561040d57611088916000916116345750611764565b6001600160801b038416156116025764ffffffffff83161580156115f2575b156115bf57602435611594576001600160601b0382165b6001600160601b037f0000000000000000000000000000000000000000000000008ac7230489e800001611611563576024356115545760405163cf88033160e01b81526020816004816001600160a01b0386165afa90811561040d57600091611535575b506001600160a01b03165b6040516370a0823160e01b81523060048201526020816024816001600160a01b0386165afa90811561040d57600091611503575b506040516323b872dd60e01b81523360048201523060248201526001600160601b038516604482015260208160648160006001600160a01b0388165af190811561040d576000916114e4575b50156114b1576040516370a0823160e01b815230600482015291602090839060249082906001600160a01b03165afa91821561040d5760009261147b575b50611200906001600160601b038516926117ef565b0361144757600054926040518060e081011067ffffffffffffffff60e08301111761141b5760e0810160409081523382526001600160a01b0384166020830152602435908201526001600160601b03841660608201526001600160801b038616608082015264ffffffffff821660a0820152600160c0820152600160401b85101561141b576001850160005561129585611669565b61143157815181546001600160a01b0319166001600160a01b03918216178255602083015160018301546040850151939290911660028410156108065760039360ff60a01b9060a01b16916affffffffffffffffffffff60a81b1617176001820155600281016001600160601b036060850151168154906001600160801b0360601b608087015160601b169163ffffffff60e01b1617179055019064ffffffffff60a08201511665ff000000000060c08454930151151560281b169165ffffffffffff1916171790553360005260016020526040600020908154600160401b81101561141b5760209661139c8264ffffffffff9560016001600160801b03950181556116c3565b81549060031b9089821b91600019901b19161790556001600160601b03604051966113c9886024356116b6565b16868901521660408501521660608301526001600160a01b031690339083907f27d0ce60b30e7976ccdc89c73d93a6540dc16fca1882f51aaaabf47b466ec4f690608090a46001600255604051908152f35b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052600060045260246000fd5b60405162461bcd60e51b815260206004820152600c60248201526b657363726f772064656c746160a01b6044820152606490fd5b9091506020813d6020116114a9575b816114976020938361172a565b8101031261047a5751906112006111eb565b3d915061148a565b60405162461bcd60e51b815260206004820152600b60248201526a195cd8dc9bddc81c1d5b1b60aa1b6044820152606490fd5b6114fd915060203d602011610406576103f8818361172a565b876111ad565b90506020813d60201161152d575b8161151e6020938361172a565b8101031261047a575186611161565b3d9150611511565b61154e915060203d60201161084457610836818361172a565b85611122565b6001600160a01b03811661112d565b60405162461bcd60e51b81526020600482015260096024820152683132b637bb9036b4b760b91b6044820152606490fd5b670de0b6b3a76400006115b96001600160801b0386166001600160601b03851661179d565b046110be565b60405162461bcd60e51b815260206004820152600b60248201526a706173742065787069727960a81b6044820152606490fd5b504264ffffffffff8416116110a7565b60405162461bcd60e51b815260206004820152600a6024820152697a65726f20707269636560b01b6044820152606490fd5b61164d915060203d602011610406576103f8818361172a565b86610b3b565b600435906001600160a01b038216820361047a57565b9060009182548110156116a25782805260021b7f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563019190565b634e487b7160e01b83526032600452602483fd5b9060028210156108065752565b80548210156116db5760005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b156116f857565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b90601f8019910116810190811067ffffffffffffffff82111761141b57604052565b9081602091031261047a5751801515810361047a5790565b1561176b57565b60405162461bcd60e51b815260206004820152600a6024820152696e6f742066616d696c7960b01b6044820152606490fd5b8181029291811591840414171561053b57565b81156117ba570490565b634e487b7160e01b600052601260045260246000fd5b9081602091031261047a57516001600160a01b038116810361047a5790565b9190820391821161053b57565b1561180357565b60405162461bcd60e51b815260206004820152600660248201526518db1bdcd95960d21b6044820152606490fd5b9190820180921161053b57565b61184790611669565b50600381015460ff8160281c1615611ac15764ffffffffff168015159081611ab6575b50611aad5760018101546001600160a01b0381169160a09190911c60ff169060028210156108065760029161199457015490602460206118e56001600160601b0385166127106118de61ffff7f000000000000000000000000000000000000000000000000000000000000000a168361179d565b04906117ef565b92604051928380926312face5360e21b82528660048301525afa90811561040d5760009161195f575b5080928115159283611921575b50505091565b90919250670de0b6b3a76400009081810291818304149015171561053b576001600160801b036119559260601c16906117b0565b111538808061191b565b906020823d60201161198c575b816119796020938361172a565b810103126119895750513861190e565b80fd5b3d915061196c565b0154670de0b6b3a76400006119bf6001600160801b036001600160601b0384169360601c168361179d565b04906127106119f261ffff7f000000000000000000000000000000000000000000000000000000000000000a168461179d565b0460405191632990643160e21b8352600483015260208083602481885afa92831561040d57600093611a7e575b506004818496604051928380926342103df160e11b82525afa91821561040d57600092611a61575b5050159283611a565750505091565b611955929350611831565b611a779250803d10610406576103f8818361172a565b3880611a47565b9080935081813d8311611aa6575b611a96818361172a565b8101031261047a57519138611a1f565b503d611a8c565b50600090600090565b90504210153861186a565b505060009060009056fea26469706673582212208a9a3c3b9c437b238d758ccdcb904f7ab04410cc8bb929ba4f63aecf7c01f42c64736f6c63430008180033