{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/collateral/rc20/MocCARC20.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\n// solhint-disable-next-line no-unused-import\nimport { MocCore } from \"../../core/MocCore.sol\";\nimport { MocOperations } from \"../../core/MocOperations.sol\";\nimport { MocQueueExecFees } from \"../../queue/MocQueueExecFees.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/**\n * @title MocCARC20: Moc Collateral Asset RC20\n * @notice Moc protocol implementation using a RC20 as Collateral Asset.\n * @dev WARNING: Fee-on-transfer tokens are NOT supported as collateral.\n *  Using them may result in incorrect accounting or loss of funds, ensure that AC token has standard ERC20 behaviors.\n */\ncontract MocCARC20 is MocOperations {\n    // ------- Structs -------\n    struct InitializeParams {\n        InitializeCoreParams initializeCoreParams;\n        // Collateral Asset Token contract address\n        address acTokenAddress;\n    }\n\n    // ------- Storage -------\n    // Collateral Asset token\n    IERC20 private _acToken;\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    // ------- Initializer -------\n    /**\n     * @notice contract initializer\n     * @param initializeParams_ contract initializer params\n     * @dev governorAddress The address that will define when a change contract is authorized\n     *      pauserAddress The address that is authorized to pause this contract\n     *      acTokenAddress Collateral Asset Token contract address\n     *      mocCoreExpansion Moc Core Expansion contract address\n     *      mocQueueAddress address for MocQueue contract\n     *      feeTokenAddress Fee Token contract address\n     *      feeTokenPriceProviderAddress Fee Token price provider contract address\n     *      tcTokenAddress Collateral Token contract address\n     *      mocFeeFlowAddress Moc Fee Flow contract address\n     *      mocAppreciationBeneficiaryAddress Moc appreciation beneficiary address\n     *      protThrld protected state threshold [PREC]\n     *      liqThrld liquidation coverage threshold [PREC]\n     *      feeRetainer pct retain on fees to be re-injected as Collateral, while paying fees with AC [PREC]\n     *      tcMintFee additional fee pct applied on mint Collateral Tokens operations [PREC]\n     *      tcRedeemFee additional fee pct applied on redeem Collateral Tokens operations [PREC]\n     *      successFee pct of the gain because Pegged Tokens devaluation that is transferred\n     *        in Collateral Asset to Moc Fee Flow during the settlement [PREC]\n     *      appreciationFactor pct of the gain because Pegged Tokens devaluation that is returned\n     *        in Pegged Tokens to appreciation beneficiary during the settlement [PREC]\n     *      settlementTimeSpan time between settlements\n     *      tcInterestCollectorAddress TC interest collector address\n     *      tcInterestRate pct interest charged to TC holders on the total collateral in the protocol [PREC]\n     *      tcInterestPaymentTimeSpan amount of seconds to wait for next TC interest payment\n     *      maxAbsoluteOpProviderAddress max absolute operation provider address\n     *      maxOpDiffProviderAddress max operation difference provider address\n     *      decayTimeSpan number of seconds that have to elapse for the linear decay factor to be 0\n     *      emaCalculationTimeSpan amount of seconds to wait between Pegged ema calculation\n     *      mocVendors address for MocVendors contract\n     *      mocQueueAddress address for MocQueue contract\n     */\n    function initialize(InitializeParams calldata initializeParams_) external initializer {\n        __MocCore_init(initializeParams_.initializeCoreParams);\n        _acToken = IERC20(initializeParams_.acTokenAddress);\n    }\n\n    // ------- Internal Functions -------\n\n    /**\n     * @inheritdoc MocCore\n     * @dev this function could revert during safeTransfer call.\n     *  safeTransfer will revert if token transfer reverts or returns 0\n     */\n    function acTransfer(address to_, uint256 amount_) internal override {\n        if (amount_ > 0) {\n            SafeERC20.safeTransfer(_acToken, to_, amount_);\n        }\n    }\n\n    /**\n     * @inheritdoc MocCore\n     */\n    function acBalanceOf(address account) internal view override returns (uint256 balance) {\n        return _acToken.balanceOf(account);\n    }\n\n    /**\n     * @inheritdoc MocCore\n     */\n    function acToken() external view override returns (address) {\n        return address(_acToken);\n    }\n\n    /**\n     * @inheritdoc MocCore\n     */\n    function refreshACBalance() external override {\n        uint256 unaccountedAcBalance = acBalanceOf(address(this)) - nACcb - qACLockedInPending;\n        // On this implementation, AC token balance is nACcb plus AC locked on pending operations\n        if (unaccountedAcBalance > 0) _depositAC(unaccountedAcBalance);\n    }\n\n    /**\n     * @inheritdoc MocOperations\n     */\n    function _lockACInPending(uint256 qACToLock_) internal override {\n        super._lockACInPending(qACToLock_);\n        SafeERC20.safeTransferFrom(_acToken, msg.sender, address(this), qACToLock_);\n    }\n\n    /**\n     * @inheritdoc MocOperations\n     */\n    function _getExecFeeSent(\n        uint256 qACmax_,\n        MocQueueExecFees.OperType operType_\n    ) internal override returns (uint256 qACmax, uint256 execFee) {\n        // For RC20 solutions, msg.value should be the execution Fee\n        // the user is willing to pay for this OperType\n        MocQueueExecFees(mocQueue).verifyExecFeeRC20(operType_, msg.value);\n        return (qACmax_, msg.value);\n    }\n\n    // ------- External Functions -------\n\n    /**\n     * @notice caller sends Collateral Asset and recipient receives Collateral Token\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not\n     *   Requires prior sender approval of Collateral Asset to this contract\n     * @param qTC_ amount of Collateral Token to mint\n     * @param qACmax_ maximum amount of Collateral Asset that can be spent\n     * @param recipient_ address who receives the Collateral Token\n     * @param vendor_ address who receives a markup, `0x0` if not using a vendor, `0x0` if not using a vendor\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function mintTC(\n        uint256 qTC_,\n        uint256 qACmax_,\n        address recipient_,\n        address vendor_\n    ) external payable returns (uint256 operId) {\n        return _mintTCtoViaVendor(qTC_, qACmax_, recipient_, vendor_);\n    }\n\n    /**\n     * @notice caller sends Collateral Asset and recipient receives Pegged Token\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not\n     *   Requires prior sender approval of Collateral Asset to this contract\n     * @param tp_ Pegged Token address to mint\n     * @param qTP_ amount of Pegged Token to mint\n     * @param qACmax_ maximum amount of Collateral Asset that can be spent\n     * @param recipient_ address who receives the Pegged Token\n     * @param vendor_ address who receives a markup, `0x0` if not using a vendor\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function mintTP(\n        address tp_,\n        uint256 qTP_,\n        uint256 qACmax_,\n        address recipient_,\n        address vendor_\n    ) external payable returns (uint256 operId) {\n        return _mintTPtoViaVendor(tp_, qTP_, qACmax_, recipient_, vendor_);\n    }\n\n    /**\n     * @notice caller sends Collateral Asset and recipient receives Collateral Token and Pegged Token\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not\n     *  Requires prior sender approval of Collateral Asset to this contract\n     *  This operation is done without checking coverage\n     *  Collateral Token and Pegged Token are minted in equivalent proportions so that its price\n     *  and global coverage are not modified.\n     *  Reverts if qAC sent are insufficient.\n     * @param tp_ Pegged Token address\n     * @param qTP_ amount of Pegged Token to mint\n     * @param qACmax_ maximum amount of Collateral Asset that can be spent\n     * @param recipient_ address who receives the Collateral Token and Pegged Token\n     * @param vendor_ address who receives a markup, `0x0` if not using a vendor\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function mintTCandTP(\n        address tp_,\n        uint256 qTP_,\n        uint256 qACmax_,\n        address recipient_,\n        address vendor_\n    ) external payable returns (uint256 operId) {\n        return _mintTCandTPtoViaVendor(tp_, qTP_, qACmax_, recipient_, vendor_);\n    }\n\n    /**\n     * @notice caller sends a Pegged Token and recipient receives another one\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not\n     * @param tpFrom_ owned Pegged Token address\n     * @param tpTo_ target Pegged Token address\n     * @param qTP_ amount of owned Pegged Token to swap\n     * @param qTPmin_ minimum amount of target Pegged Token that `recipient_` expects to receive\n     * @param qACmax_ maximum amount of Collateral Asset that can be spent in fees\n     * @param recipient_ address who receives the target Pegged Token\n     * @param vendor_ address who receives a markup, `0x0` if not using a vendor\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function swapTPforTP(\n        address tpFrom_,\n        address tpTo_,\n        uint256 qTP_,\n        uint256 qTPmin_,\n        uint256 qACmax_,\n        address recipient_,\n        address vendor_\n    ) external payable returns (uint256 operId) {\n        return _swapTPforTPtoViaVendor(tpFrom_, tpTo_, qTP_, qTPmin_, qACmax_, recipient_, vendor_);\n    }\n\n    /**\n     * @notice caller sends a Pegged Token and recipient receives Collateral Token\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not\n     * @param tp_ Pegged Token address\n     * @param qTP_ amount of owned Pegged Token to swap\n     * @param qTCmin_ minimum amount of Collateral Token that `recipient_` expects to receive\n     * @param qACmax_ maximum amount of Collateral Asset that can be spent in fees\n     * @param recipient_ address who receives the Collateral Token\n     * @param vendor_ address who receives a markup, `0x0` if not using a vendor\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function swapTPforTC(\n        address tp_,\n        uint256 qTP_,\n        uint256 qTCmin_,\n        uint256 qACmax_,\n        address recipient_,\n        address vendor_\n    ) external payable returns (uint256 operId) {\n        return _swapTPforTCtoViaVendor(tp_, qTP_, qTCmin_, qACmax_, recipient_, vendor_);\n    }\n\n    /**\n     * @notice Caller sends a Collateral Token and recipient receives Pegged Token.\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not.\n     * @param tp_ Pegged Token address\n     * @param qTC_ Amount of owned Collateral Token to swap\n     * @param qTPmin_ Minimum amount of Pegged Token that `recipient_` expects to receive\n     * @param qACmax_ Maximum amount of Collateral Asset that can be spent in fees\n     * @param recipient_ Address who receives the Pegged Token\n     * @param vendor_ address who receives a markup, `0x0` if not using a vendor\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function swapTCforTP(\n        address tp_,\n        uint256 qTC_,\n        uint256 qTPmin_,\n        uint256 qACmax_,\n        address recipient_,\n        address vendor_\n    ) external payable returns (uint256 operId) {\n        return _swapTCforTPtoViaVendor(tp_, qTC_, qTPmin_, qACmax_, recipient_, vendor_);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n","deployed_bytecode":"0x6040608081526004908136101561001557600080fd5b60009160e0908335821c91826301f1b68414613e0e5782630579188f14613d675782630c340a2414613d3d5782630c36d89714613d1c5782630d6ac46314613cd75782630db4965614613cb657826310f3538c14613c9a57826313ed7ba514613c6f5782631451c44914613c3257826314b4906d14613b6a57826316dce5f114613b495782631fb0dda014613b255782631fe6a7ad14613a45578263235e81cf1461390b57826323b98cde146138e25782632428c6981461352757826324ffaba3146134eb57826325bc6c41146134c057826328a070251461344d5782632a20d57d1461342c5782632b024aaf1461340b5782632d88af4a146133b55782632ded50f0146133945782632eccb11c146132a45782632ed35ca114613173578263333431fd1461315257826334d70ffa14613031578483633659cfe614612f9a575082633915edcb14612f6a578263391bf6cf14612e3a5782633b4ffced14612df85782633cfb09ef14612db35782633e5a575d14612d815782633f4ba83a14612c785782634017936a14612c57578263407f0e3414612c365782634114b5ab14612bd45782634250348e14612bb1578263470ff98a14612b9057826347dda6af14612adc5782634af3a6fc14612a5a5782634b74600114612a115782634e1f907a146129e65782634f0f27ee146129c5578483634f1ef286146128d7575082635210570c146128b157826352d1902d146127dc578263533a4bea1461278a57826353b16d171461274257826355b3a1e41461272157826358f32de9146126d657826359cdae4f1461268a5782635be2e5321461262b5782635c616a731461242a5782635c975abb146124025782635cfbe578146123e15782635d56c3df1461239f57826360009e0b1461237457826360ef07bf146122b0578263647846a51461228557826367a95faa1461222657826368274357146121fd5782636955cca4146121cb5782636b5488df146121aa5782636d33be63146121895782637554fffd1461216857826376228055146121475782637941df3714612097578263797709ca14611f8c57826379f9a91c14611f6b5782637a193c3114611f4a5782637b3a137714611f295782637d8e031414611eeb5782637f01c71514611ec0578263802c59c514611e9f578263826fcd5814611e7b5782638456cb5914611de95782638623987f14611da1578263883d21cb14611cc55782638cfa424114611ca45782638db6b10014611c815782638e2bdb8614611c565782638f1a383a14611c2d578263963644e214611aba5782639853c35a14611a8f5782639ad6659d14611a5e5782639c061b1b146119f75782639cabfc00146119ac5782639fd0506d1461197e578263a8833fc81461190e578263a8e9ac30146118ea578263ad4e666d14611784578263aea038dc14611763578263b03e11a014611636578263b4434c32146113c9578263b5e9ea8c1461139e578263b6d0217614611365578263b9fa641314611344578263bb4872de1461131f578263bc4e55b21461122a578263bc7765c814611205578263bf068b2d146111dc578263bfe4262114610fbf578263ce5bb47214610f4b578263d1a0faa014610e8e578263d2dc25a514610e1a578263d381c67114610dc9578263d83c54b214610da3578263d87aab6f14610d82578263d8c69aec14610c7157508163d93b80fb14610c46578163da34ba2214610bf3578163ddb6d19014610bb8578163de8d520a14610b85578163e23c135c14610b33578163e2c5e99014610ace578163e4c0aaf414610a8a578163e6a683e014610a45578163e6b1627c14610a03578163e7c25978146109de578163e8121ca814610978578163ee1f438f1461094e578163f13f405414610924578163f2015505146108df578163f30b5614146108bf578163f375cfba1461089f578163f88b14341461086b578163fa6e83bd1461084b578163fadda42414610812578163fd008fa9146107b5578163fd86f59c14610795578163fda70f8b14610775578163fdcdc11e14610676578163fddb790614610619575063fe6b92c1146105f757600080fd5b34610615578160031936011261061557602090610135549051908152f35b5080fd5b83903461061557610120366003190112610615576106356145ad565b3561013c5560243561013d5560443561013e5560643561013f556084356101405560a4356101415560c4356101425560e43561013b55610104356101435580f35b83836005926107126106b68460c461068e3686613f28565b98939592969161069f9c919c61521f565b6106a7614522565b6106b18d33615241565b6152b5565b968851946106c560c087613f76565b60018060a01b03918280921687528160209d8e998a8a01528b8d8a01523360608a01521660808801521660a086015261014f5416885196879586946323ec24b560e11b86528501906149f8565b5af193841561076a578094610733575b505061072d90615369565b51908152f35b909193508482813d8311610763575b61074c8183613f76565b810103126107605750519161072d85610722565b80fd5b503d610742565b8351903d90823e3d90fd5b50503461061557816003193601126106155760209061013c549051908152f35b50503461061557816003193601126106155760209061014c549051908152f35b90503461080e578160031936011261080e578035926001600160a01b0384168403610760576024359067ffffffffffffffff821161076057509261080161080792602095369101614106565b906144a0565b9051908152f35b8280fd5b90503461080e57602036600319011261080e5735916001600160a01b03831683036107605750610807610846602093614ce5565b614e00565b50503461061557816003193601126106155760209061013a549051908152f35b90503461080e57602036600319011261080e5735916001600160a01b0383168303610760575061080760209261080161483a565b505034610615578160031936011261061557602090610141549051908152f35b505034610615578160031936011261061557602090610131549051908152f35b90503461080e57602036600319011261080e5735916001600160a01b0383168303610760575061091b610913602093614ce5565b610137613f5a565b50549051908152f35b5050346106155781600319360112610615576101305490516001600160a01b039091168152602090f35b5050346106155781600319360112610615576101525490516001600160a01b039091168152602090f35b9190503461080e576109c86109ba916109956109da943690613fca565b9390916109a06145ad565b51631d02439560e31b602082015293849260248401614382565b03601f198101835282613f76565b6101f6546001600160a01b03166149d0565b5080f35b50503461061557816003193601126106155760209060ff61014b541690519015158152f35b90503461080e57602036600319011261080e573561018e8054821015610a415790610a2d91613f5a565b506001815491015482519182526020820152f35b8380fd5b83903461061557602036600319011261061557356001600160a01b0381169081900361061557610a736145ad565b6101f680546001600160a01b031916909117905580f35b83903461061557602036600319011261061557356001600160a01b0381169081900361061557610ab86145ad565b6001600160601b0360a01b609754161760975580f35b838334610615576060366003190112610615576001600160a01b03908335908282168203610a4157602435928084168403610b2f5761014f54163303610b20575090610b1d9160443591614fc7565b80f35b51631974847760e01b81528490fd5b8480fd5b8334610760578060031936011261076057610b4d306151af565b61013190610b6a610b6083548093614121565b61014e5490614121565b80610b73578380f35b610b7c91614375565b90558180808380f35b505034610615578160031936011261061557602090610807610bad610ba861483a565b6146ff565b905061013154614121565b90503461080e57602036600319011261080e57356001600160a01b0381169081900361080e5782829160209452610145845220549051908152f35b9190503461080e578260031936011261080e57610c0e614522565b6001600160a01b03610c1e614908565b163303610c395761014b805461ff0019166101001790558280f35b51631d2f955560e21b8152fd5b8284346107605750610807610c6b610ba8610c646020953690613e9b565b36916140b8565b90614de2565b9092915034610a415736600319011261080e57610c8c614151565b5061014f546001600160a01b03929083163303610d745790610cb2610d3d923690614302565b610cba614151565b50610cc361521f565b610ccb614522565b610d17610d088351633dad0bd760e11b6020820152610ced60248201856147b8565b60e48152610cfd61010482613f76565b866101f654166149d0565b602080825183010191016150b0565b85838a6080849a979c96989b9599015116918560c08160a084015116920151169261568e565b8061013354169760843591821682036107605750610d70959697610d6691856024350391614fc7565b5195869586614056565b0390f35b9051631974847760e01b8152fd5b50505034610615578160031936011261061557602090610155549051908152f35b50505034610615578160031936011261061557602090610807610dc461483a565b614648565b508284346107605760203660031901126107605782359067ffffffffffffffff82116107605750610e0260209361080792369101614106565b610e14610e0e82614648565b916146ff565b91615187565b6003858584610712610e328460c461068e3686613f28565b96885194610e4160c087613f76565b60018060a01b03918280921687528160209d8e998a8a01528b8d8a01523360608a01521660808801521660a086015261014f541688519687958694637e81a82160e01b86528501906149f8565b5050503461061557816003193601126106155761018f8054421015610eb1578280f35b9091610ebb61483a565b90805b8251811015610f395780807f19156e9379c7bbbce8f646ce5ee30ba860b8f954717405f3d5859a6c1a21ae608782610ef86001968961448c565b5161018e610f24610f1c610f15610f0f8685613f5a565b50614d20565b93846157ca565b938492613f5a565b5055519082519182526020820152a201610ebe565b50925050610190544201905538808280f35b5090503461080e57606036600319011261080e5780356001600160a01b0381169290839003610a415760243592610f806145ad565b61015880546001600160a01b0319169091179055662386f26fc100008311610fb25750506101595560443561015a5580f35b51632a9ffab760e21b8152fd5b838286346107605760a036600319011261076057610fdb614151565b5061014f546001600160a01b0390811633036111cc57610ffb3684614178565b91611004614151565b5061100d61521f565b611015614522565b808083611020614908565b1660248851809481936360236ab960e01b8352308b8401525af19081156111c257828092611199575b50508061105861105d92614648565b615393565b9091845180821061117d575050670de0b6b3a76400009161108361108992865192614874565b90614543565b0490811561116d57908291856110be940181815116926110b66080860194828587511661013d54926153d6565b969082614121565b966020860151808910611151575050938660a0989484806060611123978b9a9761111461114f9d998951906101346110f7838254614121565b9055611107610131918254614121565b9055836101335416615d34565b5116950151169151169261568e565b519283526020830190606080918051845260208101516020850152604081015160408501520151910152565bf35b89516354cde31360e01b81529182015260248101889052604490fd5b845163f3e39b5d60e01b81528490fd5b604491879189519263a5db715d60e01b84528301526024820152fd5b61105d93506111ba92503d8091833e6111b28183613f76565b810190615105565b909187611049565b86513d84823e3d90fd5b8351631974847760e01b81528390fd5b8482853461080e57366003190112610615576111f66145ad565b356101495560243561014a5580f35b508284346107605750610807611224610ba8610c646020953690613e9b565b90614874565b84849134610615573660031901126107605750611245614151565b5061014f546001600160a01b039190821633036113105761114f9061126d60a0943690614302565b90611276614151565b5061127f61521f565b611287614522565b6111236112d66112c7835163f5571e0160e01b60208201526112ac60248201876147b8565b60e481526112bc61010482613f76565b876101f654166149d0565b60208082518301019101614cc5565b948592919760c0611305606084019485516112f561014e918254614121565b9055836080860151169551614121565b92015116918061568e565b51631974847760e01b81529050fd5b5050503461061557816003193601126106155760209060ff60ca541690519015158152f35b5050503461061557816003193601126106155760209061015b549051908152f35b508284346107605760203660031901126107605782359067ffffffffffffffff82116107605750610dc460209361080792369101614106565b505050346106155781600319360112610615576101535490516001600160a01b039091168152602090f35b508284346107605760c0366003190112610760576113e5614151565b5061014f546001600160a01b03929083163303611627576114063685614403565b9361140f614151565b5061141861521f565b611420614522565b828061146a8661142e614908565b89518751630cff797f60e21b815230888201908152918b166001600160a01b031660208301529586949290931692849290918391604090910190565b03925af194851561161a57849185966115fc575b5061148886614648565b966114af61149883835116614ce5565b976114a3898261448c565b51996110588b8b614e47565b5050602081019283518082106115e05750506114d16115079697988451615073565b6060820198838a5116946114ff60a0850196848c8b898b5116918a8a511681526101446020522054926153d6565b999084614375565b99888501978851808d116115c457508b156115b657508560a09c6115918c9b9a97878f959a61114f9f9b8199826111239f9c6115ac9b61154c61158495608093615c70565b51960151169361155e82610137613f5a565b5061156a878254614375565b905561157a610131918254614375565b9055610135613e54565b90549060031b1c16615b05565b86516115a161014e918254614121565b905551169451614121565b915116918061568e565b895163f3e39b5d60e01b8152fd5b8a51630b63f1a760e01b815291820152602481018c9052604490fd5b604491869188519263c39b739f60e01b84528301526024820152fd5b90955061161391503d8086833e6111b28183613f76565b948761147e565b50505051903d90823e3d90fd5b51631974847760e01b81528390fd5b5083836116ff6116463685613ffc565b929391909661165361521f565b61165b614522565b6116658833615241565b6116706002346152b5565b5060a486519161168160a084613f76565b8683526020998a9485850152338985015260018060a01b0396878092166060860152166080840152888661014f54168951968795869463fa91a9a560e01b865285019060809080518352602081015160208401528160408201519160018060a01b038093166040860152826060820151166060860152015116910152565b5af1948515611758578095611724575b50509061072d91610133541630903390615ac1565b909194508582813d8311611751575b61173d8183613f76565b810103126107605750519261072d8661170f565b503d611733565b8451903d90823e3d90fd5b5050503461061557816003193601126106155760209061013d549051908152f35b508284346107605760c0366003190112610760576117a0614151565b5061014f546001600160a01b03929083163303611627576117c13685614403565b6117c9614151565b506117d261521f565b6117da614522565b6117e261483a565b926117ef85835116614ce5565b946118126117fd878761448c565b51956118098789614e47565b61014954615393565b505061182360208401958651615073565b9586156118da576118639596606085019161185b848451168360a08901978a888a511691898c511681526101456020522054926153d6565b989083614121565b98878701519a8b8b106118be575060a09a5093806080818b9a99966111148e978361114f9f9b6111239d996118a96118b1926118a060018f615c70565b519485836150dd565b610135613e54565b90549060031b1c16615d34565b6044908b8d8b51926354cde31360e01b84528301526024820152fd5b845163f3e39b5d60e01b81528890fd5b5050503461061557816003193601126106155760209061018f544210159051908152f35b5090503461080e57606036600319011261080e576001600160a01b0391813591908383168303610b2f5760443593611944614908565b163303610c395784610b1d856119788161195d88614ce5565b61196f61196982614e00565b82614e47565b602435906150dd565b33614556565b5050503461061557816003193601126106155760ca54905160109190911c6001600160a01b03168152602090f35b5090503461080e57602036600319011261080e57356001600160a01b0381169081900361080e5791819281526101366020522060ff6001825492015416825191825215156020820152f35b84823461061557606036600319011261061557356001600160a01b038181169182900361080e5760243590811680910361080e57611a336145ad565b6001600160601b0360a01b916101529083825416179055610153918254161790556044356101545580f35b50505034610615578160031936011261061557602090611a82610c6b610ba861483a565b61014a5410159051908152f35b505050346106155781600319360112610615576101465490516001600160a01b039091168152602090f35b5090503461080e5760209182600319360112610a415781359384151585036107605761013794611aea8287613f5a565b509160018060a01b03918260018095015416958551888183816378ff1b4d60e01b9b8c82525afa908115611c23578491611bf6575b509895969291909798949394978654936001965b858810611b43578b8b8b51908152f35b9091929394959698979a99838b838a8f8e611b5d91613f5a565b500154168b51928380928882525afa908115611bec57908992918891611bb5575b508615611ba75780821115611ba057505b9a9b98990196959493929190611b33565b9050611b8f565b80821015611ba05750611b8f565b809293508d8092503d8311611be5575b611bcf8183613f76565b81010312611be1579088915138611b7e565b8680fd5b503d611bc5565b8a513d89823e3d90fd5b90508881813d8311611c1c575b611c0d8183613f76565b81010312610a41575138611b1f565b503d611c03565b87513d86823e3d90fd5b50505034610615578160031936011261061557602090611c4e610ba861483a565b509051908152f35b505050346106155781600319360112610615576101585490516001600160a01b039091168152602090f35b84823461061557602036600319011261061557611c9c6145ad565b356101905580f35b5050503461061557816003193601126106155760209061014a549051908152f35b508284346107605760c03660031901126107605750611ce2614151565b5061014f546001600160a01b039081163303611d9357610d7090611d0a610d66943690614403565b92611d13614151565b50611d1c61521f565b611d24614522565b611d60610d088251637225da8960e11b6020820152611d4660248201886149f8565b60c48152611d5560e482613f76565b846101f654166149d0565b958886889397959b94969a01918251611d7d61014e918254614121565b905560a061130588836060860151169551614121565b5051631974847760e01b8152fd5b5090503461080e57602036600319011261080e5735916001600160a01b03831683036107605750610807611dd6602093614ce5565b611ddf81614e00565b6101495491614d40565b5090503461080e578260031936011261080e57611e04614522565b60ca5490601082901c6001600160a01b03163303611e6d5760ff821615611e5f575061ff0019166101001760ca55513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602090a180f35b825163866099c360e01b8152fd5b8251631d77d47760e21b8152fd5b50505034610615578160031936011261061557602090610807610c6b610ba861483a565b508284346107605760203660031901126107605750610807602092356143da565b505050346106155781600319360112610615576101c35490516001600160a01b039091168152602090f35b5090503461080e57602036600319011261080e5735916101489081548410156107605750602092611f1b91613e54565b91905490519160031b1c8152f35b50505034610615578160031936011261061557602090610157549051908152f35b50505034610615578160031936011261061557602090610134549051908152f35b50505034610615578160031936011261061557602090610142549051908152f35b8360e492611fc86106b161202a60078a96611fa73687613ee5565b98819e959b949a93979291611fba61521f565b611fc2614522565b33615241565b97611fd58a519485613f76565b60018060a01b03968780921685528160209d8e978b898901528d8801528b60608801523360808801521660a08601521660c0840152898661014f54168a519687958694636b59c22f60e01b86528501906147b8565b5af195861561208c578096612058575b505061072d929161205391610133541630903390615ac1565b615369565b909195508682813d8311612085575b6120718183613f76565b81010312610760575051938161205361203a565b503d612067565b8551903d90823e3d90fd5b848234610615576060366003190112610615576044356001600160a01b038116919082900361080e576120c86145ad565b6120d0615097565b156120f9575b356101395560243561013a5561014780546001600160a01b031916909117905580f35b61013754835b81811061210d5750506120d6565b80612119600192614e00565b61213f61212883610151613e54565b819391549060031b91821b91600019901b19161790565b9055016120ff565b50505034610615578160031936011261061557602090610156549051908152f35b50505034610615578160031936011261061557602090610139549051908152f35b50505034610615578160031936011261061557602090610190549051908152f35b50505034610615578160031936011261061557602090610149549051908152f35b50505034610615578160031936011261061557610d70906121ea61483a565b9051918291602083526020830190614022565b84346107605780600319360112610760576122166145ad565b600160ff1960ca54161760ca5580f35b5050503461061557816003193601126106155761014b5460209160ff82169182612276575b508161225a575b519015158152f35b905061226a610c6b610ba861483a565b61014a54101590612252565b60081c60ff161591508361224b565b5050503461061557816003193601126106155761012f5490516001600160a01b039091168152602090f35b60a485858461071260016122e86122c73685613ffc565b999293916122d695919561521f565b6122de614522565b6106b18633615241565b948651926122f760a085613f76565b8352876020998a958887870152338a87015260018060a01b039182809216606088015216608086015261014f54168851968795869463e97a4d6360e01b865285019060809080518352602081015160208401528160408201519160018060a01b038093166040860152826060820151166060860152015116910152565b505050346106155781600319360112610615576101335490516001600160a01b039091168152602090f35b8482853461080e576109c86109ba916123bc6109da943690613fca565b9390916123c76145ad565b51635d56c3df60e01b602082015293849260248401614382565b5050503461061557816003193601126106155760209061014e549051908152f35b5050503461061557816003193601126106155760209060ff60ca5460081c1690519015158152f35b83858334610615578160031936011261061557612445614522565b61014d908154421061261d575061014c54420190557fd3c59bda47e141a8ec5a33d241b7f71b86e30d359f83a9227d912858b60404fc8180a1809161013792835461248f81614808565b94845b828110612530575050507fae5116a8119d08673a0f1dfa7546b95da4bd54bb17feda7c61130ac7859152f69293816124e4575b6124de9083519384938452806020850152830190614022565b0390a180f35b90670de0b6b3a76400006124ff6124de926101395490614543565b049161013161250f848254614121565b9055610146546125299084906001600160a01b0316614556565b90506124c5565b61253981614e00565b6125438183614e47565b87610150916125528484613e54565b929054600393841b1c918a8313612571575b5050505050600101612492565b946125b78382969a6125bd946125b1856125a46125aa6126139b9a60019e670de0b6b3a764000093849161013a54614543565b04614543565b049261448c565b52614375565b98613e54565b81549060001990841b1b191690556125d5838b61448c565b5190848060a01b03806101475416916125ee8689613f5a565b506125fa858254614375565b905561260886610135613e54565b9054911b1c16615b05565b9088808981612564565b8351638589f7d160e01b8152fd5b8482853461080e5736600319011261061557356001600160a01b038181169182900361080e5760243590811680910361080e576126666145ad565b6001600160601b0360a01b9161012f90838254161790556101309182541617905580f35b508284346107605760203660031901126107605750610807602092356126d16126b282614e00565b916126ca6126c08483615000565b5091610137613f5a565b5054614375565b615073565b508383346106155780600319360112610615576001600160a01b03908335908282168203610a41576024359261014f54163303610b20575090610b1d9161014e828154039055614556565b5050503461061557816003193601126106155760209061015a549051908152f35b508383346106155780600319360112610615576001600160a01b03908335908282168203610a41578261014f54163303610b20575090610b1d91602435916101335416614fc7565b84823461061557602036600319011261061557356001600160a01b038116810361061557610b1d906127ba6145ad565b6101c380546001600160a01b0319166001600160a01b03909216919091179055565b83828634610760578060031936011261076057507f0000000000000000000000005316384be99310fdea0da0b3cc0d0bb9e7f0887f6001600160a01b0316300361284957602082517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b6020608492519162461bcd60e51b8352820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152fd5b84346107605780600319360112610760576128ca6145ad565b60ff1960ca541660ca5580f35b808386806003193601126129c15781356001600160a01b038082168203610b2f576024359367ffffffffffffffff85116129bd57366023860112156129bd578401359061292f61292683613fae565b94519485613f76565b81845236602483870101116129bd57610b1d956020836129b0946024600199018389013786010152807f0000000000000000000000005316384be99310fdea0da0b3cc0d0bb9e7f0887f1690612987823014156141d5565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc541614614236565b6129b86145ad565b614aa1565b8580fd5b5050fd5b5050503461061557816003193601126106155760209061013b549051908152f35b505050346106155781600319360112610615576101475490516001600160a01b039091168152602090f35b5090503461080e57602036600319011261080e57356101378054821015610a415790612a3c91613f5a565b50805460019091015482519182526001600160a01b03166020820152f35b84849134610615573660031901126107605750612a75614151565b5061014f546001600160a01b039190821633036113105761114f90612a9d60a0943690614302565b90612aa6614151565b50612aaf61521f565b612ab7614522565b6111236112d66112c7835163d9b6c2e560e01b60208201526112ac60248201876147b8565b5090503461080e578160031936011261080e57356001600160a01b038181169291839003610a415760243592818416918285036129bd57612b7192612b1f614522565b612b298633615241565b612b32306151af565b90855193632ab7831f60e01b602086015260248501523360448501526064840152608483015260848252612b6760a483613f76565b6101f654166149d0565b92602084805181010312610760575061072d6020809401518093614556565b508284346107605760203660031901126107605750610807602092356142cc565b84823461061557602036600319011261061557612bcc6145ad565b3561014c5580f35b5090503461080e578160031936011261080e578035916001600160a01b038084168403610b2f57612c03614908565b163303610c395783612c23612c1785614ce5565b61091361196982614e00565b50612c316024358254614375565b905580f35b5050503461061557816003193601126106155760209061013e549051908152f35b50505034610615578160031936011261061557602090610807610e0261483a565b5090503461080e578260031936011261080e5760ca549060ff8260081c1615612d735760018060a01b03808360101c163314159081612cf6575b50611e6d5760ff821615611e5f575061ff00191660ca55513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602090a180f35b609754855163d994d6d560e01b81523385820152925060209183916024918391165afa908115612d69578591612d2f575b501538612cb2565b90506020813d602011612d61575b81612d4a60209383613f76565b81010312610b2f57612d5b90614144565b38612d27565b3d9150612d3d565b84513d87823e3d90fd5b8251637c7fd07960e01b8152fd5b838286346107605750612d9e610ba8610c64612da6933690613e9b565b819291614de2565b9082519182526020820152f35b84823461061557602036600319011261061557356001600160a01b0381169081900361061557612de16145ad565b61014f80546001600160a01b031916909117905580f35b5090503461080e578160031936011261080e5735916001600160a01b03831683036107605750610807612e2c602093614ce5565b610149549060243590614d40565b83853461076057610100908160031936011261076057612e58614151565b5061014f546001600160a01b03959086163303612f5c57612e7b84519384613f76565b35858116810361061557825260243585811681036106155760208301526044358383015260643560608301526080820191608435835260a43594868616860361080e5760a0820195865260c4358781168103610a415760c083015260e4359287841684036107605750869361114f959360a098612f466112c76109ba612f3b886115ac986111239a01968752612f0f614151565b50612f1861521f565b612f20614522565b8a516370f090ed60e11b602082015292839160248301614a3d565b836101f654166149d0565b98899692919b86516115a161014e918254614121565b8351631974847760e01b8152fd5b5090503461080e57602036600319011261080e5735916101389081548410156107605750602092611f1b91613e54565b92505034610615576020366003190112610615576001600160a01b03929035838116810361080e57612ff984610b1d957f0000000000000000000000005316384be99310fdea0da0b3cc0d0bb9e7f0887f1690612987823014156141d5565b6130016145ad565b61301661300d84613fae565b92519283613f76565b828252601f1961302584613fae565b01366020840137614aa1565b8385913661303f9085613ee5565b94929591909861304d61521f565b613055614522565b61305f8a33615241565b61306a6006346152b5565b508751926130789084613f76565b600160a01b6001900380809516968785528160209c8d9589878901528b8d89015260608801523360808801521660a08601521660c08401528361014f5416885193849263e4e1b72960e01b845283016130d0916147b8565b818a5a9260e493f1968715613147578097613113575b505061072d93929161310091610133541630903390615ac1565b61310981614ce5565b5030903390615ac1565b909196508782813d8311613140575b61312c8183613f76565b8101031261076057505194816131006130e6565b503d613122565b8651903d90823e3d90fd5b5050503461061557816003193601126106155760209061013f549051908152f35b8484838360031936011261080e576001600160a01b0393813585811690819003610b2f576024358681168091036129bd576044359260a43594888616988987036132a05760c4359681881680980361329c57906131d861324295949392611fba61521f565b6131e560096084356152b5565b978951936131f561010086613f76565b87855260209c8d9687870152898c87015260643560608701528a60808701523360a087015260c086015284015261014f5416908989518096819582946334975a4160e01b84528301614a3d565b03925af195861561208c578096613268575b505061072d92918161310961205393614ce5565b909195508682813d8311613295575b6132818183613f76565b810103126107605750519381612053613254565b503d613277565b8980fd5b8880fd5b5083836132b13684613f28565b92939190966132be61521f565b6132c6614522565b6132d08833615241565b6132da81346152b5565b508551926132e960c085613f76565b600160a01b6001900380809216958686528160209b8c968a888a01528b8901523360608901521660808701521660a085015261014f54168651938492636426c5db60e11b8452830161333a916149f8565b81885a9260c493f1948515611758578095613360575b5050908161310961072d93614ce5565b909194508582813d831161338d575b6133798183613f76565b810103126107605750519261072d86613350565b503d61336f565b50505034610615578160031936011261061557602090610143549051908152f35b84823461061557602036600319011261061557356001600160a01b0381168103610615576133e16145ad565b60ca805462010000600160b01b03191660109290921b62010000600160b01b031691909117905580f35b5050503461061557816003193601126106155760209061014d549051908152f35b50505034610615578160031936011261061557602090610140549051908152f35b83858334610615578160031936011261061557613468614522565b6001600160a01b0380613479614908565b1633036134b1576109da929361014b61010061ff00198254161790555191631149b6af60e01b60208401528252612b67602483613f76565b508251631d2f955560e21b8152fd5b505050346106155781600319360112610615576102295490516001600160a01b039091168152602090f35b5090503461080e57602036600319011261080e57356001600160a01b0381169081900361080e5782829160209452610144845220549051908152f35b5090503461080e5761042036600319011261080e5782549060ff8260081c1615918280936138d5575b80156138be575b156138645760ff198116600117855582613853575b5060ff845460081c169061357f826148a8565b6001600160a01b036103a43581811693919290849003611be1576001600160601b0360a01b936101f690858254161790556103643583811680910361384f576103843584811681036132a0576001916135d7856148a8565b6135e0856148a8565b6135e9856148a8565b6135f2856148a8565b866097541617609755613604846148a8565b60ca5490620100008360b01b039060101b169061ff018360b01b031916171760ca5561362f826148a8565b35828116809103611be15761014f9084825416179055602435828116809103611be15761012f9084825416179055604435828116809103611be1576101309084825416179055606435828116809103611be1576101339084825416179055608435828116809103611be157610146908482541617905560a435828116809103611be157610147908482541617905560c4356101495560e43561014a556101043561013c556101243561013d556101443561013e556101643561013f5561018435610140556101a435610141556101c435610142556101e43561013b55610204356101435561022435610139556102443561013a55610264358061014c556102843583811680910361384f5761015890858254161790556102a435610159556102c435908161015a556102e4358481168091036132a0576101529086825416179055610304358481168091036132a057610153908682541617905561032435610154554261015755420161014d55420161015b5561014b8054610344358015158091036132a05762ff00009060101b169062ffffff19161790556103c4356137d5826148a8565b8061019055420161018f556103e4358281168103611be1576127ba6137f9926148a8565b61040435908116809103610b2f5761022991825416179055613819575080f35b60207f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989161ff001984541684555160018152a180f35b8780fd5b61ffff19166101011784553861356c565b835162461bcd60e51b8152602081840152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608490fd5b50303b1580156135575750600160ff821614613557565b50600160ff821610613550565b5050503461061557816003193601126106155760209060ff61014b5460081c1690519015158152f35b508284346107605760a03660031901126107605750613928614151565b5061014f546001600160a01b03919082163303611310576139b49061394d3685614178565b92613956614151565b5061395f61521f565b613967614522565b670de0b6b3a764000061398a61108361398161180961483a565b88519291614874565b04908285019080825116916139ac6080880193858486511661013c54926153d6565b969085614375565b9660208101948551808a11613a2957508815613a19578760a0968a96866115ac898286996115918f9a6111239a61114f9e6060835193015116906101346139fc848254614375565b9055613a0c610131918254614375565b9055846101335416615b05565b865163f3e39b5d60e01b81528a90fd5b8a8a6044928a5192630b63f1a760e01b84528301526024820152fd5b5090503461080e57602036600319011261080e57803591821515809303610a4157609754815163d994d6d560e01b815233848201526001600160a01b03916020908290602490829086165afa908115613b1b578691613ae1575b50159081613acf575b50613ac257505061014b9060ff8019835416911617905580f35b51631dd1b1b560e21b8152fd5b905060ca5460101c1633141538613aa8565b90506020813d602011613b13575b81613afc60209383613f76565b810103126129bd57613b0d90614144565b38613a9f565b3d9150613aef565b83513d88823e3d90fd5b50505034610615578160031936011261061557602090610807611224610ba861483a565b50505034610615578160031936011261061557602090610154549051908152f35b83859136613b789085613ee5565b9394959291613b8899919961521f565b613b90614522565b613b9a8a33615241565b6008613ba5916152b5565b95875193613bb39085613f76565b600160a01b6001900380809216958686528160209c8d968a888a01528c8901528a60608901523360808901521660a08701521660c085015261014f541687519384926263744760e11b84528301613c09916147b8565b81895a9260e493f195861561208c57809661326857505061072d92918161310961205393614ce5565b508284346107605750610807610ba8613c69613c516020953690613e9b565b9290613c61610dc43686846140b8565b9336916140b8565b9161477b565b5050503461061557816003193601126106155761014f5490516001600160a01b039091168152602090f35b508284346107605750611c4e610ba8610c646020943690613e9b565b50505034610615578160031936011261061557602090610159549051908152f35b84823461061557602036600319011261061557356001600160a01b0381169081900361061557613d056145ad565b61014680546001600160a01b031916909117905580f35b5050503461061557816003193601126106155760209061018f549051908152f35b5050503461061557816003193601126106155760975490516001600160a01b039091168152602090f35b5090503461080e578260031936011261080e57613d82614522565b61015b9081544210613e005750610b1d9160209161015a5442019055613dec6101319182547f0e37fda283839477a1b77e29acf8336c0e13a5daa967913df0fe5ad258c0822f670de0b6b3a7640000613dde6101595484614543565b0495869351848152a1614121565b9055610158546001600160a01b0316614556565b8251631097267160e11b8152fd5b5090503461080e57602036600319011261080e5735916101359081548410156107605750602092613e3e91613e54565b905491519160018060a01b039160031b1c168152f35b8054821015613e6c5760005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b35906001600160a01b0382168203613e9657565b600080fd5b9190602083820312613e9657823567ffffffffffffffff93848211613e9657019080601f83011215613e96578135938411613e965760208460051b83010111613e96576020019190565b91908260c0910312613e9657613efa82613e82565b91602081013591604082013591606081013591613f2560a0613f1e60808501613e82565b9301613e82565b90565b908160a0910312613e9657613f3c81613e82565b91602082013591604081013591613f256080613f1e60608501613e82565b8054821015613e6c5760005260206000209060011b0190600090565b90601f8019910116810190811067ffffffffffffffff821117613f9857604052565b634e487b7160e01b600052604160045260246000fd5b67ffffffffffffffff8111613f9857601f01601f191660200190565b809291039160e08312613e965780356001600160a01b0381168103613e965760c09093601f190112613e965760200190565b9190826080910312613e9657813591602081013591613f256060613f1e60408501613e82565b90815180825260208080930193019160005b828110614042575050505090565b835185529381019392810192600101614034565b909594929361409e9460809361010084019884526020840152604083015260608201520190606080918051845260208101516020850152604081015160408501520151910152565b565b67ffffffffffffffff8111613f985760051b60200190565b92916140c3826140a0565b916140d16040519384613f76565b829481845260208094019160051b8101928311613e9657905b8282106140f75750505050565b813581529083019083016140ea565b9080601f83011215613e9657816020613f25933591016140b8565b9190820391821161412e57565b634e487b7160e01b600052601160045260246000fd5b51908115158203613e9657565b60405190614160608083613f76565b60006060838281528260208201528260408201520152565b91908260a0910312613e965760405161419260a082613f76565b60806141d081839580358552602081013560208601526141b460408201613e82565b60408601526141c560608201613e82565b606086015201613e82565b910152565b156141dc57565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608490fd5b1561423d57565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608490fd5b9190916000838201938412911290801582169115161761412e57565b8181039291600013801582851316918412161761412e57565b61015454156142fb576142e1613f2591614eea565b6142f56142ee8284614297565b91836142b3565b91614f6a565b5060001990565b91908260e0910312613e965760405161431c60e082613f76565b60c06141d081839561432d81613e82565b855260208101356020860152604081013560408601526060810135606086015261435960808201613e82565b608086015261436a60a08201613e82565b60a086015201613e82565b9190820180921161412e57565b6001600160a01b03918216815260e081019392909160c09160a0916143a682613e82565b1660208501526020810135604085015260408101356060850152606081013560808501526080810135828501520135910152565b61015454156142fb576143ef613f2591614eea565b6142f56143fc82846142b3565b9183614297565b91908260c0910312613e965760405161441d60c082613f76565b60a06141d081839561442e81613e82565b8552602081013560208601526040810135604086015261445060608201613e82565b606086015261446160808201613e82565b608086015201613e82565b8115614476570490565b634e487b7160e01b600052601260045260246000fd5b8051821015613e6c5760209160051b010190565b906144eb906144e66144cc6144b483614648565b946144e06144d36144c4866146ff565b949093614ce5565b809661448c565b5194856101495491614d40565b9561477b565b614eac565b90670de0b6b3a763ffff19810190811161412e57670de0b6b3a76400009081810291818304149015171561412e57613f2591614ecf565b60ff60ca5460081c1661453157565b60405163783bb6c960e11b8152600490fd5b8181029291811591840414171561412e57565b9080614560575050565b6102295460405163a9059cbb60e01b60208201526001600160a01b039384166024820152604481019290925261409e92166145a882606481015b03601f198101845283613f76565b6159cf565b60975460405163d994d6d560e01b815233600482015290602090829060249082906001600160a01b03165afa90811561463c57600091614602575b50156145f057565b604051631dd1b1b560e21b8152600490fd5b90506020813d602011614634575b8161461d60209383613f76565b81010312613e965761462e90614144565b386145e8565b3d9150614610565b6040513d6000823e3d90fd5b60008061014954926101378054906000925b82841061467d5750505050811561467557613f25925061446c565b505060011b90565b909192949361468c868361448c565b51906146a661469b8389615000565b506126ca8987613f5a565b91670de0b6b3a76400009283810293818504149015171561412e576146ef6146f5926146e98a6146e48d6146dc8760019a615073565b968793614d40565b614543565b90614375565b96614375565b950192919061465a565b906000916000906101378054906000925b8284106147365750505050614732670de0b6b3a7640000916101395490614543565b0490565b90919293956147716126d161476b6001936146e96147548a8861448c565b5161475f818c615000565b95906126ca8d8c613f5a565b98614375565b9401929190614710565b909161478a9061013154614121565b90670de0b6b3a76400009182810292818404149015171561412e57613f25926147b291614543565b906142b3565b60c0908160018060a01b03918281511685526020810151602086015260408101516040860152606081015160608601528260808201511660808601528260a08201511660a0860152015116910152565b90614812826140a0565b61481f6040519182613f76565b8281528092614830601f19916140a0565b0190602036910137565b610137549061484882614808565b9160005b818110614857575050565b80614863600192614e00565b61486d828761448c565b520161484c565b906101345490811561489957613f25926148946126d19261013154614121565b614121565b505050670de0b6b3a764000090565b156148af57565b60405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b61014f5460405163018761ed60e61b81526001600160a01b03916020908290600490829086165afa90811561463c5760009161494357501690565b6020813d602011614974575b8161495c60209383613f76565b81010312610615575190828216820361076057501690565b3d915061494f565b6149866027613fae565b906149946040519283613f76565b60278252660819985a5b195960ca1b6040837f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c60208201520152565b90613f25916000806149e061497c565b93602081519101845af46149f2615285565b91615b9c565b60a09081600180821b03918281511685526020810151602086015260408101516040860152826060820151166060860152826080820151166080860152015116910152565b91909160e06101008201938160018060a01b03918281511685528260208201511660208601526040810151604086015260608101516060860152608081015160808601528260a08201511660a08601528260c08201511660c0860152015116910152565b9060ff7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435416600014614ad9575061409e9150615728565b6040516352d1902d60e01b8152602093919291906001600160a01b038316908581600481855afa60009181614c58575b50614b6a5760405162461bcd60e51b815260048101879052602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608490fd5b9394937fc9f76b5ec45e5cdef99837d7b6d2467235c1df8933c8ca56df5c35afa2c7d44401614c0157614b9c83615728565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a283511590811591614bf9575b50614bd757505050565b600080614bf694614be661497c565b9481519101845af46149f2615285565b50565b905038614bcd565b60405162461bcd60e51b815260048101859052602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b9091508681813d8311614c80575b614c708183613f76565b81010312613e9657519038614b09565b503d614c66565b9190826080910312613e9657604051614ca1608082613f76565b60608082948051845260208101516020850152604081015160408501520151910152565b909160c082840312613e9657613f25825193604060208501519401614c87565b6001600160a01b0316600090815261013660205260409020600181015460ff1615614d0e575490565b60405163e6c4247b60e01b8152600490fd5b90604051614d2f604082613f76565b602060018294805484520154910152565b61018e9082614d4f8284613f5a565b50549261018f54421015614dbc575b5050614d6c90610148613e54565b90549060031b1c670de0b6b3a763ffff19810190811161412e57614d9892614d9391614543565b61446c565b90670de0b6b3a7640000820180921161412e5780821115614db7575090565b905090565b82935090614dd3610f0f614d6c94614dd894613f5a565b6157ca565b9190508238614d5e565b8015614df8576126d1613f259261013154614121565b505060001990565b614e0c90610137613f5a565b50600101546001600160a01b0316614e2381615818565b91909115614e2f575090565b60249060405190637f6e4db960e01b82526004820152fd5b614e4f615097565b614e57575050565b61212881614e6884614ea894615880565b614e9e614e7783610150613e54565b614e8a8294925492838360031b1c614297565b919060031b91821b91600019901b19161790565b9055610151613e54565b9055565b818102929160008212600160ff1b82141661412e57818405149015171561412e57565b811561447657600160ff1b811460001983141661412e570590565b614ef7614f019142614375565b6101575490614121565b90670de0b6b3a7640000918281029080820484149015171561412e5761015454614f2a9161446c565b82811015614f615782039180831161412e5780614f5c613f2592614f518661015554614543565b049461015654614eac565b614ecf565b50600091508190565b9091614f746158d2565b929080821015614fbd578391614f8991614121565b931115614fb85781811015614fb057614fa191614121565b60011c80821015614db7575090565b505050600090565b505090565b5050505050600090565b60405163a9059cbb60e01b60208201526001600160a01b039092166024830152604482019290925261409e916145a8826064810161459a565b9091600092600092615010615097565b615019575b5050565b818161503661502d61504094610150613e54565b93905492615880565b9160031b1c614297565b6000811361504c575050565b6125a492945061506f9193508093670de0b6b3a764000093849161013a54614543565b0491565b90670de0b6b3a76400009182810292818404149015171561412e57613f259161446c565b61013954158015906150a65790565b5061013a54151590565b919061010083820312613e9657825192602081015192613f25604083015193608060608501519401614c87565b6150ec6150f591610137613f5a565b50918254614121565b9055614ea8610131918254614121565b9190604083820312613e9657825192602090818101519067ffffffffffffffff8211613e9657019180601f84011215613e96578251615143816140a0565b936151516040519586613f76565b818552838086019260051b820101928311613e96578301905b828210615178575050505090565b8151815290830190830161516a565b82826151929261477b565b906000821315614fb057613f25926151a991614874565b9061446c565b610229546040516370a0823160e01b81526001600160a01b0392831660048201529160209183916024918391165afa90811561463c576000916151f0575090565b90506020813d602011615217575b8161520b60209383613f76565b81010312613e96575190565b3d91506151fe565b60ff61014b5460081c1661522f57565b604051631ca61d7760e01b8152600490fd5b60ff61014b5460101c1615918261526d575b505061525b57565b604051636f97b88360e01b8152600490fd5b6001600160a01b039182169116141590503880615253565b3d156152b0573d9061529682613fae565b916152a46040519384613f76565b82523d6000602084013e565b606090565b61014f546001600160a01b0393926000918516803b1561080e57604051630155ee3160e01b815291600a811015615355576044838593819360048301523460248301525afa801561534a5761533a575b5080808093953490615315614908565b165af1615320615285565b501561532857565b6040516312171d8360e31b8152600490fd5b8161534491613f76565b38615305565b6040513d84823e3d90fd5b634e487b7160e01b84526021600452602484fd5b61409e9061014e61537b828254614375565b905561022954309033906001600160a01b0316615ac1565b919061539e906146ff565b9190926153ab8385614de2565b90808211156153b8575050565b6044925060405191637912120160e01b835260048301526024820152fd5b9093926000926000956153e7614151565b96936001600160a01b0391859190831680615615575b5061012f54604051636eb1769f60e11b81526001600160a01b038316600482015230602482015260209490918116908583604481855afa92831561560a578894939291879187946155d3575b50836154ab575b5050505050505086015115615467575b5050509190565b9091925061547f670de0b6b3a7640000928392614543565b048085529082156154a35761549b920490816040860152614375565b388080615460565b50905061549b565b8d896154bb836101305416615818565b9890986154cc575b97505050615450565b670de0b6b3a76400006154f06154e68b936154f695614543565b6101435490614543565b0461446c565b81840181815297908d9081156155c85750916155176060926155239461446c565b91829101528751614375565b80945b10948515615555575b5050505050615546575b80808085818d898b6154c3565b81905260608801523880615539565b6040516370a0823160e01b81529116600482015292935090829060249082905afa9081156155bd578491615590575b5010388085818061552f565b90508481813d83116155b6575b6155a78183613f76565b81010312610a41575138615584565b503d61559d565b6040513d86823e3d90fd5b925050508094615526565b92935093945081813d8311615603575b6155ed8183613f76565b81010312610b2f57908588949392519238615449565b503d6155e3565b6040513d87823e3d90fd5b9095506020836101c35416916024604051809481936364a731e960e01b835260048301525afa801561534a57829061565a575b615653915084614543565b94386153fd565b506020813d602011615686575b8161567460209383613f76565b81010312610615576156539051615648565b3d9150615667565b9261409e94919293825115156000146156fe575060406156f9926156f1670de0b6b3a76400006156c361013b54845190614543565b046101316156d2828254614375565b90556156eb60018060a01b036101465416918451614121565b90614556565b015190614556565b614556565b9060606156f99361572060018060a01b03610146541660208301519086615b79565b015191615b79565b803b1561576f577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b03909216919091179055565b60405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b602081519101805192670de0b6b3a76400009384039084821161412e576157f76146e99261473295614543565b9251614543565b9190826040910312613e9657613f25602083519301614144565b604080516359e02dd760e01b81529291839060049082906001600160a01b03165afa91821561463c5760009060009361585057509190565b905061587591925060403d604011615879575b61586d8183613f76565b8101906157fe565b9091565b503d615863565b61588c81610137613f5a565b505490670de0b6b3a76400009182810292818404149015171561412e57613f25926158cc6158bf6147b293610151613e54565b90549060031b1c8461446c565b9261446c565b61015254604080516359e02dd760e01b80825293929091906001600160a01b039081168284600481845afa80156159c4576000946000916159a1575b501561598a575061015354169080519485528085600481855afa801561597f5760009560009161595c575b50156159455750509190565b6024925051906305e8989360e11b82526004820152fd5b9050816159769296503d87116158795761586d8183613f76565b94909438615939565b50513d6000823e3d90fd5b6024908351906305e8989360e11b82526004820152fd5b90506159bb919450833d85116158795761586d8183613f76565b9390933861590e565b83513d6000823e3d90fd5b602091615a32916001600160a01b03166000806159eb86613fae565b936159f96040519586613f76565b8685527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656487860152868151910182855af16149f2615285565b8051828115918215615aa2575b5050905015615a4b5750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b8380929350010312613e965781615ab99101614144565b808238615a3f565b6040516323b872dd60e01b60208201526001600160a01b03928316602482015292909116604483015260648083019390935291815261409e916145a8608483613f76565b6040516340c10f1960e01b81526001600160a01b039283166004820152602481019390935260209183916044918391600091165af1801561463c57615b475750565b6020813d602011615b71575b81615b6060209383613f76565b81010312613e9657614bf690614144565b3d9150615b53565b919081615b8557505050565b61012f5461409e93906001600160a01b0316615ac1565b91929015615bfe5750815115615bb0575090565b3b15615bb95790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015615c115750805190602001fd5b6040519062461bcd60e51b82528160208060048301528251908160248401526000935b828510615c57575050604492506000838284010152601f80199101168101030190fd5b8481018201518686016044015293810193859350615c34565b61015454156150155780615c826158d2565b919093615c8f6000614eea565b9401938291615d28575b019360008512615d1f57845b840391818511615ce7575050818111615cc957505061015555610156554261015755565b60449250604051916306da41e560e11b835260048301526024820152fd5b9080859211615d0d57604491604051916306da41e560e11b835260048301526024820152fd5b604051630fb4fd3560e11b8152600490fd5b84600003615ca5565b90508160000390615c99565b6001600160a01b0316803b15613e9657604051632770a7eb60e21b815230600482015260248101929092526000908290604490829084905af1801561463c57615d7a5750565b600061409e91613f7656fea26469706673582212203df412547bddfa4178b48a0f8e6f363ef64a0bdf26c90f5592ff40ed805f329e64736f6c63430008180033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"london","libraries":{},"optimizer":{"details":{"yulDetails":{"optimizerSteps":"dhfoDgvulfnTUtnIf[xa[r]EscLMcCTUtTOntnfDIulLculVcul[j]Tpeulxa[rul]xa[r]cLgvifCTUca[r]LSsTOtfDnca[r]Iulc]jmul[jul]VcTOculjmul"}},"enabled":true,"runs":200},"outputSelection":{"*":{"":["*"],"*":["*"]}},"remappings":["npm/@moneyonchain/oracles@3.0.10/:@moc/moc-main/=npm/main-sc-protocol-v2@3.0.9/","npm/@moneyonchain/oracles@3.0.10/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/@uniswap/swap-router-contracts@1.3.1/:@uniswap/v3-core/=npm/@uniswap/v3-core@1.0.1/","npm/main-sc-protocol-v2@3.0.9/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","npm/main-sc-protocol-v2@3.0.9/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/main-sc-protocol-v2@3.0.9/:@uniswap/swap-router-contracts/=npm/@uniswap/swap-router-contracts@1.3.1/","project/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","project/:moc-main-latest/=npm/main-sc-protocol-v2@3.0.9/"],"viaIR":true},"optimization_runs":200,"sourcify_repo_url":null,"decoded_constructor_args":null,"compiler_version":"v0.8.24+commit.e11b9ed9","is_verified_via_verifier_alliance":false,"verified_at":"2026-08-21T13:00:31.552922Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60a08060405234620000e157306080526000549060ff8260081c166200008f575060ff8082160362000053575b604051615dbb9081620000e782396080518181816127f20152818161295a0152612fcc0152f35b60ff90811916176000557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160ff8152a1386200002c565b62461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608490fd5b600080fdfe6040608081526004908136101561001557600080fd5b60009160e0908335821c91826301f1b68414613e0e5782630579188f14613d675782630c340a2414613d3d5782630c36d89714613d1c5782630d6ac46314613cd75782630db4965614613cb657826310f3538c14613c9a57826313ed7ba514613c6f5782631451c44914613c3257826314b4906d14613b6a57826316dce5f114613b495782631fb0dda014613b255782631fe6a7ad14613a45578263235e81cf1461390b57826323b98cde146138e25782632428c6981461352757826324ffaba3146134eb57826325bc6c41146134c057826328a070251461344d5782632a20d57d1461342c5782632b024aaf1461340b5782632d88af4a146133b55782632ded50f0146133945782632eccb11c146132a45782632ed35ca114613173578263333431fd1461315257826334d70ffa14613031578483633659cfe614612f9a575082633915edcb14612f6a578263391bf6cf14612e3a5782633b4ffced14612df85782633cfb09ef14612db35782633e5a575d14612d815782633f4ba83a14612c785782634017936a14612c57578263407f0e3414612c365782634114b5ab14612bd45782634250348e14612bb1578263470ff98a14612b9057826347dda6af14612adc5782634af3a6fc14612a5a5782634b74600114612a115782634e1f907a146129e65782634f0f27ee146129c5578483634f1ef286146128d7575082635210570c146128b157826352d1902d146127dc578263533a4bea1461278a57826353b16d171461274257826355b3a1e41461272157826358f32de9146126d657826359cdae4f1461268a5782635be2e5321461262b5782635c616a731461242a5782635c975abb146124025782635cfbe578146123e15782635d56c3df1461239f57826360009e0b1461237457826360ef07bf146122b0578263647846a51461228557826367a95faa1461222657826368274357146121fd5782636955cca4146121cb5782636b5488df146121aa5782636d33be63146121895782637554fffd1461216857826376228055146121475782637941df3714612097578263797709ca14611f8c57826379f9a91c14611f6b5782637a193c3114611f4a5782637b3a137714611f295782637d8e031414611eeb5782637f01c71514611ec0578263802c59c514611e9f578263826fcd5814611e7b5782638456cb5914611de95782638623987f14611da1578263883d21cb14611cc55782638cfa424114611ca45782638db6b10014611c815782638e2bdb8614611c565782638f1a383a14611c2d578263963644e214611aba5782639853c35a14611a8f5782639ad6659d14611a5e5782639c061b1b146119f75782639cabfc00146119ac5782639fd0506d1461197e578263a8833fc81461190e578263a8e9ac30146118ea578263ad4e666d14611784578263aea038dc14611763578263b03e11a014611636578263b4434c32146113c9578263b5e9ea8c1461139e578263b6d0217614611365578263b9fa641314611344578263bb4872de1461131f578263bc4e55b21461122a578263bc7765c814611205578263bf068b2d146111dc578263bfe4262114610fbf578263ce5bb47214610f4b578263d1a0faa014610e8e578263d2dc25a514610e1a578263d381c67114610dc9578263d83c54b214610da3578263d87aab6f14610d82578263d8c69aec14610c7157508163d93b80fb14610c46578163da34ba2214610bf3578163ddb6d19014610bb8578163de8d520a14610b85578163e23c135c14610b33578163e2c5e99014610ace578163e4c0aaf414610a8a578163e6a683e014610a45578163e6b1627c14610a03578163e7c25978146109de578163e8121ca814610978578163ee1f438f1461094e578163f13f405414610924578163f2015505146108df578163f30b5614146108bf578163f375cfba1461089f578163f88b14341461086b578163fa6e83bd1461084b578163fadda42414610812578163fd008fa9146107b5578163fd86f59c14610795578163fda70f8b14610775578163fdcdc11e14610676578163fddb790614610619575063fe6b92c1146105f757600080fd5b34610615578160031936011261061557602090610135549051908152f35b5080fd5b83903461061557610120366003190112610615576106356145ad565b3561013c5560243561013d5560443561013e5560643561013f556084356101405560a4356101415560c4356101425560e43561013b55610104356101435580f35b83836005926107126106b68460c461068e3686613f28565b98939592969161069f9c919c61521f565b6106a7614522565b6106b18d33615241565b6152b5565b968851946106c560c087613f76565b60018060a01b03918280921687528160209d8e998a8a01528b8d8a01523360608a01521660808801521660a086015261014f5416885196879586946323ec24b560e11b86528501906149f8565b5af193841561076a578094610733575b505061072d90615369565b51908152f35b909193508482813d8311610763575b61074c8183613f76565b810103126107605750519161072d85610722565b80fd5b503d610742565b8351903d90823e3d90fd5b50503461061557816003193601126106155760209061013c549051908152f35b50503461061557816003193601126106155760209061014c549051908152f35b90503461080e578160031936011261080e578035926001600160a01b0384168403610760576024359067ffffffffffffffff821161076057509261080161080792602095369101614106565b906144a0565b9051908152f35b8280fd5b90503461080e57602036600319011261080e5735916001600160a01b03831683036107605750610807610846602093614ce5565b614e00565b50503461061557816003193601126106155760209061013a549051908152f35b90503461080e57602036600319011261080e5735916001600160a01b0383168303610760575061080760209261080161483a565b505034610615578160031936011261061557602090610141549051908152f35b505034610615578160031936011261061557602090610131549051908152f35b90503461080e57602036600319011261080e5735916001600160a01b0383168303610760575061091b610913602093614ce5565b610137613f5a565b50549051908152f35b5050346106155781600319360112610615576101305490516001600160a01b039091168152602090f35b5050346106155781600319360112610615576101525490516001600160a01b039091168152602090f35b9190503461080e576109c86109ba916109956109da943690613fca565b9390916109a06145ad565b51631d02439560e31b602082015293849260248401614382565b03601f198101835282613f76565b6101f6546001600160a01b03166149d0565b5080f35b50503461061557816003193601126106155760209060ff61014b541690519015158152f35b90503461080e57602036600319011261080e573561018e8054821015610a415790610a2d91613f5a565b506001815491015482519182526020820152f35b8380fd5b83903461061557602036600319011261061557356001600160a01b0381169081900361061557610a736145ad565b6101f680546001600160a01b031916909117905580f35b83903461061557602036600319011261061557356001600160a01b0381169081900361061557610ab86145ad565b6001600160601b0360a01b609754161760975580f35b838334610615576060366003190112610615576001600160a01b03908335908282168203610a4157602435928084168403610b2f5761014f54163303610b20575090610b1d9160443591614fc7565b80f35b51631974847760e01b81528490fd5b8480fd5b8334610760578060031936011261076057610b4d306151af565b61013190610b6a610b6083548093614121565b61014e5490614121565b80610b73578380f35b610b7c91614375565b90558180808380f35b505034610615578160031936011261061557602090610807610bad610ba861483a565b6146ff565b905061013154614121565b90503461080e57602036600319011261080e57356001600160a01b0381169081900361080e5782829160209452610145845220549051908152f35b9190503461080e578260031936011261080e57610c0e614522565b6001600160a01b03610c1e614908565b163303610c395761014b805461ff0019166101001790558280f35b51631d2f955560e21b8152fd5b8284346107605750610807610c6b610ba8610c646020953690613e9b565b36916140b8565b90614de2565b9092915034610a415736600319011261080e57610c8c614151565b5061014f546001600160a01b03929083163303610d745790610cb2610d3d923690614302565b610cba614151565b50610cc361521f565b610ccb614522565b610d17610d088351633dad0bd760e11b6020820152610ced60248201856147b8565b60e48152610cfd61010482613f76565b866101f654166149d0565b602080825183010191016150b0565b85838a6080849a979c96989b9599015116918560c08160a084015116920151169261568e565b8061013354169760843591821682036107605750610d70959697610d6691856024350391614fc7565b5195869586614056565b0390f35b9051631974847760e01b8152fd5b50505034610615578160031936011261061557602090610155549051908152f35b50505034610615578160031936011261061557602090610807610dc461483a565b614648565b508284346107605760203660031901126107605782359067ffffffffffffffff82116107605750610e0260209361080792369101614106565b610e14610e0e82614648565b916146ff565b91615187565b6003858584610712610e328460c461068e3686613f28565b96885194610e4160c087613f76565b60018060a01b03918280921687528160209d8e998a8a01528b8d8a01523360608a01521660808801521660a086015261014f541688519687958694637e81a82160e01b86528501906149f8565b5050503461061557816003193601126106155761018f8054421015610eb1578280f35b9091610ebb61483a565b90805b8251811015610f395780807f19156e9379c7bbbce8f646ce5ee30ba860b8f954717405f3d5859a6c1a21ae608782610ef86001968961448c565b5161018e610f24610f1c610f15610f0f8685613f5a565b50614d20565b93846157ca565b938492613f5a565b5055519082519182526020820152a201610ebe565b50925050610190544201905538808280f35b5090503461080e57606036600319011261080e5780356001600160a01b0381169290839003610a415760243592610f806145ad565b61015880546001600160a01b0319169091179055662386f26fc100008311610fb25750506101595560443561015a5580f35b51632a9ffab760e21b8152fd5b838286346107605760a036600319011261076057610fdb614151565b5061014f546001600160a01b0390811633036111cc57610ffb3684614178565b91611004614151565b5061100d61521f565b611015614522565b808083611020614908565b1660248851809481936360236ab960e01b8352308b8401525af19081156111c257828092611199575b50508061105861105d92614648565b615393565b9091845180821061117d575050670de0b6b3a76400009161108361108992865192614874565b90614543565b0490811561116d57908291856110be940181815116926110b66080860194828587511661013d54926153d6565b969082614121565b966020860151808910611151575050938660a0989484806060611123978b9a9761111461114f9d998951906101346110f7838254614121565b9055611107610131918254614121565b9055836101335416615d34565b5116950151169151169261568e565b519283526020830190606080918051845260208101516020850152604081015160408501520151910152565bf35b89516354cde31360e01b81529182015260248101889052604490fd5b845163f3e39b5d60e01b81528490fd5b604491879189519263a5db715d60e01b84528301526024820152fd5b61105d93506111ba92503d8091833e6111b28183613f76565b810190615105565b909187611049565b86513d84823e3d90fd5b8351631974847760e01b81528390fd5b8482853461080e57366003190112610615576111f66145ad565b356101495560243561014a5580f35b508284346107605750610807611224610ba8610c646020953690613e9b565b90614874565b84849134610615573660031901126107605750611245614151565b5061014f546001600160a01b039190821633036113105761114f9061126d60a0943690614302565b90611276614151565b5061127f61521f565b611287614522565b6111236112d66112c7835163f5571e0160e01b60208201526112ac60248201876147b8565b60e481526112bc61010482613f76565b876101f654166149d0565b60208082518301019101614cc5565b948592919760c0611305606084019485516112f561014e918254614121565b9055836080860151169551614121565b92015116918061568e565b51631974847760e01b81529050fd5b5050503461061557816003193601126106155760209060ff60ca541690519015158152f35b5050503461061557816003193601126106155760209061015b549051908152f35b508284346107605760203660031901126107605782359067ffffffffffffffff82116107605750610dc460209361080792369101614106565b505050346106155781600319360112610615576101535490516001600160a01b039091168152602090f35b508284346107605760c0366003190112610760576113e5614151565b5061014f546001600160a01b03929083163303611627576114063685614403565b9361140f614151565b5061141861521f565b611420614522565b828061146a8661142e614908565b89518751630cff797f60e21b815230888201908152918b166001600160a01b031660208301529586949290931692849290918391604090910190565b03925af194851561161a57849185966115fc575b5061148886614648565b966114af61149883835116614ce5565b976114a3898261448c565b51996110588b8b614e47565b5050602081019283518082106115e05750506114d16115079697988451615073565b6060820198838a5116946114ff60a0850196848c8b898b5116918a8a511681526101446020522054926153d6565b999084614375565b99888501978851808d116115c457508b156115b657508560a09c6115918c9b9a97878f959a61114f9f9b8199826111239f9c6115ac9b61154c61158495608093615c70565b51960151169361155e82610137613f5a565b5061156a878254614375565b905561157a610131918254614375565b9055610135613e54565b90549060031b1c16615b05565b86516115a161014e918254614121565b905551169451614121565b915116918061568e565b895163f3e39b5d60e01b8152fd5b8a51630b63f1a760e01b815291820152602481018c9052604490fd5b604491869188519263c39b739f60e01b84528301526024820152fd5b90955061161391503d8086833e6111b28183613f76565b948761147e565b50505051903d90823e3d90fd5b51631974847760e01b81528390fd5b5083836116ff6116463685613ffc565b929391909661165361521f565b61165b614522565b6116658833615241565b6116706002346152b5565b5060a486519161168160a084613f76565b8683526020998a9485850152338985015260018060a01b0396878092166060860152166080840152888661014f54168951968795869463fa91a9a560e01b865285019060809080518352602081015160208401528160408201519160018060a01b038093166040860152826060820151166060860152015116910152565b5af1948515611758578095611724575b50509061072d91610133541630903390615ac1565b909194508582813d8311611751575b61173d8183613f76565b810103126107605750519261072d8661170f565b503d611733565b8451903d90823e3d90fd5b5050503461061557816003193601126106155760209061013d549051908152f35b508284346107605760c0366003190112610760576117a0614151565b5061014f546001600160a01b03929083163303611627576117c13685614403565b6117c9614151565b506117d261521f565b6117da614522565b6117e261483a565b926117ef85835116614ce5565b946118126117fd878761448c565b51956118098789614e47565b61014954615393565b505061182360208401958651615073565b9586156118da576118639596606085019161185b848451168360a08901978a888a511691898c511681526101456020522054926153d6565b989083614121565b98878701519a8b8b106118be575060a09a5093806080818b9a99966111148e978361114f9f9b6111239d996118a96118b1926118a060018f615c70565b519485836150dd565b610135613e54565b90549060031b1c16615d34565b6044908b8d8b51926354cde31360e01b84528301526024820152fd5b845163f3e39b5d60e01b81528890fd5b5050503461061557816003193601126106155760209061018f544210159051908152f35b5090503461080e57606036600319011261080e576001600160a01b0391813591908383168303610b2f5760443593611944614908565b163303610c395784610b1d856119788161195d88614ce5565b61196f61196982614e00565b82614e47565b602435906150dd565b33614556565b5050503461061557816003193601126106155760ca54905160109190911c6001600160a01b03168152602090f35b5090503461080e57602036600319011261080e57356001600160a01b0381169081900361080e5791819281526101366020522060ff6001825492015416825191825215156020820152f35b84823461061557606036600319011261061557356001600160a01b038181169182900361080e5760243590811680910361080e57611a336145ad565b6001600160601b0360a01b916101529083825416179055610153918254161790556044356101545580f35b50505034610615578160031936011261061557602090611a82610c6b610ba861483a565b61014a5410159051908152f35b505050346106155781600319360112610615576101465490516001600160a01b039091168152602090f35b5090503461080e5760209182600319360112610a415781359384151585036107605761013794611aea8287613f5a565b509160018060a01b03918260018095015416958551888183816378ff1b4d60e01b9b8c82525afa908115611c23578491611bf6575b509895969291909798949394978654936001965b858810611b43578b8b8b51908152f35b9091929394959698979a99838b838a8f8e611b5d91613f5a565b500154168b51928380928882525afa908115611bec57908992918891611bb5575b508615611ba75780821115611ba057505b9a9b98990196959493929190611b33565b9050611b8f565b80821015611ba05750611b8f565b809293508d8092503d8311611be5575b611bcf8183613f76565b81010312611be1579088915138611b7e565b8680fd5b503d611bc5565b8a513d89823e3d90fd5b90508881813d8311611c1c575b611c0d8183613f76565b81010312610a41575138611b1f565b503d611c03565b87513d86823e3d90fd5b50505034610615578160031936011261061557602090611c4e610ba861483a565b509051908152f35b505050346106155781600319360112610615576101585490516001600160a01b039091168152602090f35b84823461061557602036600319011261061557611c9c6145ad565b356101905580f35b5050503461061557816003193601126106155760209061014a549051908152f35b508284346107605760c03660031901126107605750611ce2614151565b5061014f546001600160a01b039081163303611d9357610d7090611d0a610d66943690614403565b92611d13614151565b50611d1c61521f565b611d24614522565b611d60610d088251637225da8960e11b6020820152611d4660248201886149f8565b60c48152611d5560e482613f76565b846101f654166149d0565b958886889397959b94969a01918251611d7d61014e918254614121565b905560a061130588836060860151169551614121565b5051631974847760e01b8152fd5b5090503461080e57602036600319011261080e5735916001600160a01b03831683036107605750610807611dd6602093614ce5565b611ddf81614e00565b6101495491614d40565b5090503461080e578260031936011261080e57611e04614522565b60ca5490601082901c6001600160a01b03163303611e6d5760ff821615611e5f575061ff0019166101001760ca55513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602090a180f35b825163866099c360e01b8152fd5b8251631d77d47760e21b8152fd5b50505034610615578160031936011261061557602090610807610c6b610ba861483a565b508284346107605760203660031901126107605750610807602092356143da565b505050346106155781600319360112610615576101c35490516001600160a01b039091168152602090f35b5090503461080e57602036600319011261080e5735916101489081548410156107605750602092611f1b91613e54565b91905490519160031b1c8152f35b50505034610615578160031936011261061557602090610157549051908152f35b50505034610615578160031936011261061557602090610134549051908152f35b50505034610615578160031936011261061557602090610142549051908152f35b8360e492611fc86106b161202a60078a96611fa73687613ee5565b98819e959b949a93979291611fba61521f565b611fc2614522565b33615241565b97611fd58a519485613f76565b60018060a01b03968780921685528160209d8e978b898901528d8801528b60608801523360808801521660a08601521660c0840152898661014f54168a519687958694636b59c22f60e01b86528501906147b8565b5af195861561208c578096612058575b505061072d929161205391610133541630903390615ac1565b615369565b909195508682813d8311612085575b6120718183613f76565b81010312610760575051938161205361203a565b503d612067565b8551903d90823e3d90fd5b848234610615576060366003190112610615576044356001600160a01b038116919082900361080e576120c86145ad565b6120d0615097565b156120f9575b356101395560243561013a5561014780546001600160a01b031916909117905580f35b61013754835b81811061210d5750506120d6565b80612119600192614e00565b61213f61212883610151613e54565b819391549060031b91821b91600019901b19161790565b9055016120ff565b50505034610615578160031936011261061557602090610156549051908152f35b50505034610615578160031936011261061557602090610139549051908152f35b50505034610615578160031936011261061557602090610190549051908152f35b50505034610615578160031936011261061557602090610149549051908152f35b50505034610615578160031936011261061557610d70906121ea61483a565b9051918291602083526020830190614022565b84346107605780600319360112610760576122166145ad565b600160ff1960ca54161760ca5580f35b5050503461061557816003193601126106155761014b5460209160ff82169182612276575b508161225a575b519015158152f35b905061226a610c6b610ba861483a565b61014a54101590612252565b60081c60ff161591508361224b565b5050503461061557816003193601126106155761012f5490516001600160a01b039091168152602090f35b60a485858461071260016122e86122c73685613ffc565b999293916122d695919561521f565b6122de614522565b6106b18633615241565b948651926122f760a085613f76565b8352876020998a958887870152338a87015260018060a01b039182809216606088015216608086015261014f54168851968795869463e97a4d6360e01b865285019060809080518352602081015160208401528160408201519160018060a01b038093166040860152826060820151166060860152015116910152565b505050346106155781600319360112610615576101335490516001600160a01b039091168152602090f35b8482853461080e576109c86109ba916123bc6109da943690613fca565b9390916123c76145ad565b51635d56c3df60e01b602082015293849260248401614382565b5050503461061557816003193601126106155760209061014e549051908152f35b5050503461061557816003193601126106155760209060ff60ca5460081c1690519015158152f35b83858334610615578160031936011261061557612445614522565b61014d908154421061261d575061014c54420190557fd3c59bda47e141a8ec5a33d241b7f71b86e30d359f83a9227d912858b60404fc8180a1809161013792835461248f81614808565b94845b828110612530575050507fae5116a8119d08673a0f1dfa7546b95da4bd54bb17feda7c61130ac7859152f69293816124e4575b6124de9083519384938452806020850152830190614022565b0390a180f35b90670de0b6b3a76400006124ff6124de926101395490614543565b049161013161250f848254614121565b9055610146546125299084906001600160a01b0316614556565b90506124c5565b61253981614e00565b6125438183614e47565b87610150916125528484613e54565b929054600393841b1c918a8313612571575b5050505050600101612492565b946125b78382969a6125bd946125b1856125a46125aa6126139b9a60019e670de0b6b3a764000093849161013a54614543565b04614543565b049261448c565b52614375565b98613e54565b81549060001990841b1b191690556125d5838b61448c565b5190848060a01b03806101475416916125ee8689613f5a565b506125fa858254614375565b905561260886610135613e54565b9054911b1c16615b05565b9088808981612564565b8351638589f7d160e01b8152fd5b8482853461080e5736600319011261061557356001600160a01b038181169182900361080e5760243590811680910361080e576126666145ad565b6001600160601b0360a01b9161012f90838254161790556101309182541617905580f35b508284346107605760203660031901126107605750610807602092356126d16126b282614e00565b916126ca6126c08483615000565b5091610137613f5a565b5054614375565b615073565b508383346106155780600319360112610615576001600160a01b03908335908282168203610a41576024359261014f54163303610b20575090610b1d9161014e828154039055614556565b5050503461061557816003193601126106155760209061015a549051908152f35b508383346106155780600319360112610615576001600160a01b03908335908282168203610a41578261014f54163303610b20575090610b1d91602435916101335416614fc7565b84823461061557602036600319011261061557356001600160a01b038116810361061557610b1d906127ba6145ad565b6101c380546001600160a01b0319166001600160a01b03909216919091179055565b83828634610760578060031936011261076057507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316300361284957602082517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b6020608492519162461bcd60e51b8352820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152fd5b84346107605780600319360112610760576128ca6145ad565b60ff1960ca541660ca5580f35b808386806003193601126129c15781356001600160a01b038082168203610b2f576024359367ffffffffffffffff85116129bd57366023860112156129bd578401359061292f61292683613fae565b94519485613f76565b81845236602483870101116129bd57610b1d956020836129b0946024600199018389013786010152807f00000000000000000000000000000000000000000000000000000000000000001690612987823014156141d5565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc541614614236565b6129b86145ad565b614aa1565b8580fd5b5050fd5b5050503461061557816003193601126106155760209061013b549051908152f35b505050346106155781600319360112610615576101475490516001600160a01b039091168152602090f35b5090503461080e57602036600319011261080e57356101378054821015610a415790612a3c91613f5a565b50805460019091015482519182526001600160a01b03166020820152f35b84849134610615573660031901126107605750612a75614151565b5061014f546001600160a01b039190821633036113105761114f90612a9d60a0943690614302565b90612aa6614151565b50612aaf61521f565b612ab7614522565b6111236112d66112c7835163d9b6c2e560e01b60208201526112ac60248201876147b8565b5090503461080e578160031936011261080e57356001600160a01b038181169291839003610a415760243592818416918285036129bd57612b7192612b1f614522565b612b298633615241565b612b32306151af565b90855193632ab7831f60e01b602086015260248501523360448501526064840152608483015260848252612b6760a483613f76565b6101f654166149d0565b92602084805181010312610760575061072d6020809401518093614556565b508284346107605760203660031901126107605750610807602092356142cc565b84823461061557602036600319011261061557612bcc6145ad565b3561014c5580f35b5090503461080e578160031936011261080e578035916001600160a01b038084168403610b2f57612c03614908565b163303610c395783612c23612c1785614ce5565b61091361196982614e00565b50612c316024358254614375565b905580f35b5050503461061557816003193601126106155760209061013e549051908152f35b50505034610615578160031936011261061557602090610807610e0261483a565b5090503461080e578260031936011261080e5760ca549060ff8260081c1615612d735760018060a01b03808360101c163314159081612cf6575b50611e6d5760ff821615611e5f575061ff00191660ca55513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602090a180f35b609754855163d994d6d560e01b81523385820152925060209183916024918391165afa908115612d69578591612d2f575b501538612cb2565b90506020813d602011612d61575b81612d4a60209383613f76565b81010312610b2f57612d5b90614144565b38612d27565b3d9150612d3d565b84513d87823e3d90fd5b8251637c7fd07960e01b8152fd5b838286346107605750612d9e610ba8610c64612da6933690613e9b565b819291614de2565b9082519182526020820152f35b84823461061557602036600319011261061557356001600160a01b0381169081900361061557612de16145ad565b61014f80546001600160a01b031916909117905580f35b5090503461080e578160031936011261080e5735916001600160a01b03831683036107605750610807612e2c602093614ce5565b610149549060243590614d40565b83853461076057610100908160031936011261076057612e58614151565b5061014f546001600160a01b03959086163303612f5c57612e7b84519384613f76565b35858116810361061557825260243585811681036106155760208301526044358383015260643560608301526080820191608435835260a43594868616860361080e5760a0820195865260c4358781168103610a415760c083015260e4359287841684036107605750869361114f959360a098612f466112c76109ba612f3b886115ac986111239a01968752612f0f614151565b50612f1861521f565b612f20614522565b8a516370f090ed60e11b602082015292839160248301614a3d565b836101f654166149d0565b98899692919b86516115a161014e918254614121565b8351631974847760e01b8152fd5b5090503461080e57602036600319011261080e5735916101389081548410156107605750602092611f1b91613e54565b92505034610615576020366003190112610615576001600160a01b03929035838116810361080e57612ff984610b1d957f00000000000000000000000000000000000000000000000000000000000000001690612987823014156141d5565b6130016145ad565b61301661300d84613fae565b92519283613f76565b828252601f1961302584613fae565b01366020840137614aa1565b8385913661303f9085613ee5565b94929591909861304d61521f565b613055614522565b61305f8a33615241565b61306a6006346152b5565b508751926130789084613f76565b600160a01b6001900380809516968785528160209c8d9589878901528b8d89015260608801523360808801521660a08601521660c08401528361014f5416885193849263e4e1b72960e01b845283016130d0916147b8565b818a5a9260e493f1968715613147578097613113575b505061072d93929161310091610133541630903390615ac1565b61310981614ce5565b5030903390615ac1565b909196508782813d8311613140575b61312c8183613f76565b8101031261076057505194816131006130e6565b503d613122565b8651903d90823e3d90fd5b5050503461061557816003193601126106155760209061013f549051908152f35b8484838360031936011261080e576001600160a01b0393813585811690819003610b2f576024358681168091036129bd576044359260a43594888616988987036132a05760c4359681881680980361329c57906131d861324295949392611fba61521f565b6131e560096084356152b5565b978951936131f561010086613f76565b87855260209c8d9687870152898c87015260643560608701528a60808701523360a087015260c086015284015261014f5416908989518096819582946334975a4160e01b84528301614a3d565b03925af195861561208c578096613268575b505061072d92918161310961205393614ce5565b909195508682813d8311613295575b6132818183613f76565b810103126107605750519381612053613254565b503d613277565b8980fd5b8880fd5b5083836132b13684613f28565b92939190966132be61521f565b6132c6614522565b6132d08833615241565b6132da81346152b5565b508551926132e960c085613f76565b600160a01b6001900380809216958686528160209b8c968a888a01528b8901523360608901521660808701521660a085015261014f54168651938492636426c5db60e11b8452830161333a916149f8565b81885a9260c493f1948515611758578095613360575b5050908161310961072d93614ce5565b909194508582813d831161338d575b6133798183613f76565b810103126107605750519261072d86613350565b503d61336f565b50505034610615578160031936011261061557602090610143549051908152f35b84823461061557602036600319011261061557356001600160a01b0381168103610615576133e16145ad565b60ca805462010000600160b01b03191660109290921b62010000600160b01b031691909117905580f35b5050503461061557816003193601126106155760209061014d549051908152f35b50505034610615578160031936011261061557602090610140549051908152f35b83858334610615578160031936011261061557613468614522565b6001600160a01b0380613479614908565b1633036134b1576109da929361014b61010061ff00198254161790555191631149b6af60e01b60208401528252612b67602483613f76565b508251631d2f955560e21b8152fd5b505050346106155781600319360112610615576102295490516001600160a01b039091168152602090f35b5090503461080e57602036600319011261080e57356001600160a01b0381169081900361080e5782829160209452610144845220549051908152f35b5090503461080e5761042036600319011261080e5782549060ff8260081c1615918280936138d5575b80156138be575b156138645760ff198116600117855582613853575b5060ff845460081c169061357f826148a8565b6001600160a01b036103a43581811693919290849003611be1576001600160601b0360a01b936101f690858254161790556103643583811680910361384f576103843584811681036132a0576001916135d7856148a8565b6135e0856148a8565b6135e9856148a8565b6135f2856148a8565b866097541617609755613604846148a8565b60ca5490620100008360b01b039060101b169061ff018360b01b031916171760ca5561362f826148a8565b35828116809103611be15761014f9084825416179055602435828116809103611be15761012f9084825416179055604435828116809103611be1576101309084825416179055606435828116809103611be1576101339084825416179055608435828116809103611be157610146908482541617905560a435828116809103611be157610147908482541617905560c4356101495560e43561014a556101043561013c556101243561013d556101443561013e556101643561013f5561018435610140556101a435610141556101c435610142556101e43561013b55610204356101435561022435610139556102443561013a55610264358061014c556102843583811680910361384f5761015890858254161790556102a435610159556102c435908161015a556102e4358481168091036132a0576101529086825416179055610304358481168091036132a057610153908682541617905561032435610154554261015755420161014d55420161015b5561014b8054610344358015158091036132a05762ff00009060101b169062ffffff19161790556103c4356137d5826148a8565b8061019055420161018f556103e4358281168103611be1576127ba6137f9926148a8565b61040435908116809103610b2f5761022991825416179055613819575080f35b60207f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989161ff001984541684555160018152a180f35b8780fd5b61ffff19166101011784553861356c565b835162461bcd60e51b8152602081840152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608490fd5b50303b1580156135575750600160ff821614613557565b50600160ff821610613550565b5050503461061557816003193601126106155760209060ff61014b5460081c1690519015158152f35b508284346107605760a03660031901126107605750613928614151565b5061014f546001600160a01b03919082163303611310576139b49061394d3685614178565b92613956614151565b5061395f61521f565b613967614522565b670de0b6b3a764000061398a61108361398161180961483a565b88519291614874565b04908285019080825116916139ac6080880193858486511661013c54926153d6565b969085614375565b9660208101948551808a11613a2957508815613a19578760a0968a96866115ac898286996115918f9a6111239a61114f9e6060835193015116906101346139fc848254614375565b9055613a0c610131918254614375565b9055846101335416615b05565b865163f3e39b5d60e01b81528a90fd5b8a8a6044928a5192630b63f1a760e01b84528301526024820152fd5b5090503461080e57602036600319011261080e57803591821515809303610a4157609754815163d994d6d560e01b815233848201526001600160a01b03916020908290602490829086165afa908115613b1b578691613ae1575b50159081613acf575b50613ac257505061014b9060ff8019835416911617905580f35b51631dd1b1b560e21b8152fd5b905060ca5460101c1633141538613aa8565b90506020813d602011613b13575b81613afc60209383613f76565b810103126129bd57613b0d90614144565b38613a9f565b3d9150613aef565b83513d88823e3d90fd5b50505034610615578160031936011261061557602090610807611224610ba861483a565b50505034610615578160031936011261061557602090610154549051908152f35b83859136613b789085613ee5565b9394959291613b8899919961521f565b613b90614522565b613b9a8a33615241565b6008613ba5916152b5565b95875193613bb39085613f76565b600160a01b6001900380809216958686528160209c8d968a888a01528c8901528a60608901523360808901521660a08701521660c085015261014f541687519384926263744760e11b84528301613c09916147b8565b81895a9260e493f195861561208c57809661326857505061072d92918161310961205393614ce5565b508284346107605750610807610ba8613c69613c516020953690613e9b565b9290613c61610dc43686846140b8565b9336916140b8565b9161477b565b5050503461061557816003193601126106155761014f5490516001600160a01b039091168152602090f35b508284346107605750611c4e610ba8610c646020943690613e9b565b50505034610615578160031936011261061557602090610159549051908152f35b84823461061557602036600319011261061557356001600160a01b0381169081900361061557613d056145ad565b61014680546001600160a01b031916909117905580f35b5050503461061557816003193601126106155760209061018f549051908152f35b5050503461061557816003193601126106155760975490516001600160a01b039091168152602090f35b5090503461080e578260031936011261080e57613d82614522565b61015b9081544210613e005750610b1d9160209161015a5442019055613dec6101319182547f0e37fda283839477a1b77e29acf8336c0e13a5daa967913df0fe5ad258c0822f670de0b6b3a7640000613dde6101595484614543565b0495869351848152a1614121565b9055610158546001600160a01b0316614556565b8251631097267160e11b8152fd5b5090503461080e57602036600319011261080e5735916101359081548410156107605750602092613e3e91613e54565b905491519160018060a01b039160031b1c168152f35b8054821015613e6c5760005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b35906001600160a01b0382168203613e9657565b600080fd5b9190602083820312613e9657823567ffffffffffffffff93848211613e9657019080601f83011215613e96578135938411613e965760208460051b83010111613e96576020019190565b91908260c0910312613e9657613efa82613e82565b91602081013591604082013591606081013591613f2560a0613f1e60808501613e82565b9301613e82565b90565b908160a0910312613e9657613f3c81613e82565b91602082013591604081013591613f256080613f1e60608501613e82565b8054821015613e6c5760005260206000209060011b0190600090565b90601f8019910116810190811067ffffffffffffffff821117613f9857604052565b634e487b7160e01b600052604160045260246000fd5b67ffffffffffffffff8111613f9857601f01601f191660200190565b809291039160e08312613e965780356001600160a01b0381168103613e965760c09093601f190112613e965760200190565b9190826080910312613e9657813591602081013591613f256060613f1e60408501613e82565b90815180825260208080930193019160005b828110614042575050505090565b835185529381019392810192600101614034565b909594929361409e9460809361010084019884526020840152604083015260608201520190606080918051845260208101516020850152604081015160408501520151910152565b565b67ffffffffffffffff8111613f985760051b60200190565b92916140c3826140a0565b916140d16040519384613f76565b829481845260208094019160051b8101928311613e9657905b8282106140f75750505050565b813581529083019083016140ea565b9080601f83011215613e9657816020613f25933591016140b8565b9190820391821161412e57565b634e487b7160e01b600052601160045260246000fd5b51908115158203613e9657565b60405190614160608083613f76565b60006060838281528260208201528260408201520152565b91908260a0910312613e965760405161419260a082613f76565b60806141d081839580358552602081013560208601526141b460408201613e82565b60408601526141c560608201613e82565b606086015201613e82565b910152565b156141dc57565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608490fd5b1561423d57565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608490fd5b9190916000838201938412911290801582169115161761412e57565b8181039291600013801582851316918412161761412e57565b61015454156142fb576142e1613f2591614eea565b6142f56142ee8284614297565b91836142b3565b91614f6a565b5060001990565b91908260e0910312613e965760405161431c60e082613f76565b60c06141d081839561432d81613e82565b855260208101356020860152604081013560408601526060810135606086015261435960808201613e82565b608086015261436a60a08201613e82565b60a086015201613e82565b9190820180921161412e57565b6001600160a01b03918216815260e081019392909160c09160a0916143a682613e82565b1660208501526020810135604085015260408101356060850152606081013560808501526080810135828501520135910152565b61015454156142fb576143ef613f2591614eea565b6142f56143fc82846142b3565b9183614297565b91908260c0910312613e965760405161441d60c082613f76565b60a06141d081839561442e81613e82565b8552602081013560208601526040810135604086015261445060608201613e82565b606086015261446160808201613e82565b608086015201613e82565b8115614476570490565b634e487b7160e01b600052601260045260246000fd5b8051821015613e6c5760209160051b010190565b906144eb906144e66144cc6144b483614648565b946144e06144d36144c4866146ff565b949093614ce5565b809661448c565b5194856101495491614d40565b9561477b565b614eac565b90670de0b6b3a763ffff19810190811161412e57670de0b6b3a76400009081810291818304149015171561412e57613f2591614ecf565b60ff60ca5460081c1661453157565b60405163783bb6c960e11b8152600490fd5b8181029291811591840414171561412e57565b9080614560575050565b6102295460405163a9059cbb60e01b60208201526001600160a01b039384166024820152604481019290925261409e92166145a882606481015b03601f198101845283613f76565b6159cf565b60975460405163d994d6d560e01b815233600482015290602090829060249082906001600160a01b03165afa90811561463c57600091614602575b50156145f057565b604051631dd1b1b560e21b8152600490fd5b90506020813d602011614634575b8161461d60209383613f76565b81010312613e965761462e90614144565b386145e8565b3d9150614610565b6040513d6000823e3d90fd5b60008061014954926101378054906000925b82841061467d5750505050811561467557613f25925061446c565b505060011b90565b909192949361468c868361448c565b51906146a661469b8389615000565b506126ca8987613f5a565b91670de0b6b3a76400009283810293818504149015171561412e576146ef6146f5926146e98a6146e48d6146dc8760019a615073565b968793614d40565b614543565b90614375565b96614375565b950192919061465a565b906000916000906101378054906000925b8284106147365750505050614732670de0b6b3a7640000916101395490614543565b0490565b90919293956147716126d161476b6001936146e96147548a8861448c565b5161475f818c615000565b95906126ca8d8c613f5a565b98614375565b9401929190614710565b909161478a9061013154614121565b90670de0b6b3a76400009182810292818404149015171561412e57613f25926147b291614543565b906142b3565b60c0908160018060a01b03918281511685526020810151602086015260408101516040860152606081015160608601528260808201511660808601528260a08201511660a0860152015116910152565b90614812826140a0565b61481f6040519182613f76565b8281528092614830601f19916140a0565b0190602036910137565b610137549061484882614808565b9160005b818110614857575050565b80614863600192614e00565b61486d828761448c565b520161484c565b906101345490811561489957613f25926148946126d19261013154614121565b614121565b505050670de0b6b3a764000090565b156148af57565b60405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b61014f5460405163018761ed60e61b81526001600160a01b03916020908290600490829086165afa90811561463c5760009161494357501690565b6020813d602011614974575b8161495c60209383613f76565b81010312610615575190828216820361076057501690565b3d915061494f565b6149866027613fae565b906149946040519283613f76565b60278252660819985a5b195960ca1b6040837f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c60208201520152565b90613f25916000806149e061497c565b93602081519101845af46149f2615285565b91615b9c565b60a09081600180821b03918281511685526020810151602086015260408101516040860152826060820151166060860152826080820151166080860152015116910152565b91909160e06101008201938160018060a01b03918281511685528260208201511660208601526040810151604086015260608101516060860152608081015160808601528260a08201511660a08601528260c08201511660c0860152015116910152565b9060ff7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435416600014614ad9575061409e9150615728565b6040516352d1902d60e01b8152602093919291906001600160a01b038316908581600481855afa60009181614c58575b50614b6a5760405162461bcd60e51b815260048101879052602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608490fd5b9394937fc9f76b5ec45e5cdef99837d7b6d2467235c1df8933c8ca56df5c35afa2c7d44401614c0157614b9c83615728565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a283511590811591614bf9575b50614bd757505050565b600080614bf694614be661497c565b9481519101845af46149f2615285565b50565b905038614bcd565b60405162461bcd60e51b815260048101859052602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b9091508681813d8311614c80575b614c708183613f76565b81010312613e9657519038614b09565b503d614c66565b9190826080910312613e9657604051614ca1608082613f76565b60608082948051845260208101516020850152604081015160408501520151910152565b909160c082840312613e9657613f25825193604060208501519401614c87565b6001600160a01b0316600090815261013660205260409020600181015460ff1615614d0e575490565b60405163e6c4247b60e01b8152600490fd5b90604051614d2f604082613f76565b602060018294805484520154910152565b61018e9082614d4f8284613f5a565b50549261018f54421015614dbc575b5050614d6c90610148613e54565b90549060031b1c670de0b6b3a763ffff19810190811161412e57614d9892614d9391614543565b61446c565b90670de0b6b3a7640000820180921161412e5780821115614db7575090565b905090565b82935090614dd3610f0f614d6c94614dd894613f5a565b6157ca565b9190508238614d5e565b8015614df8576126d1613f259261013154614121565b505060001990565b614e0c90610137613f5a565b50600101546001600160a01b0316614e2381615818565b91909115614e2f575090565b60249060405190637f6e4db960e01b82526004820152fd5b614e4f615097565b614e57575050565b61212881614e6884614ea894615880565b614e9e614e7783610150613e54565b614e8a8294925492838360031b1c614297565b919060031b91821b91600019901b19161790565b9055610151613e54565b9055565b818102929160008212600160ff1b82141661412e57818405149015171561412e57565b811561447657600160ff1b811460001983141661412e570590565b614ef7614f019142614375565b6101575490614121565b90670de0b6b3a7640000918281029080820484149015171561412e5761015454614f2a9161446c565b82811015614f615782039180831161412e5780614f5c613f2592614f518661015554614543565b049461015654614eac565b614ecf565b50600091508190565b9091614f746158d2565b929080821015614fbd578391614f8991614121565b931115614fb85781811015614fb057614fa191614121565b60011c80821015614db7575090565b505050600090565b505090565b5050505050600090565b60405163a9059cbb60e01b60208201526001600160a01b039092166024830152604482019290925261409e916145a8826064810161459a565b9091600092600092615010615097565b615019575b5050565b818161503661502d61504094610150613e54565b93905492615880565b9160031b1c614297565b6000811361504c575050565b6125a492945061506f9193508093670de0b6b3a764000093849161013a54614543565b0491565b90670de0b6b3a76400009182810292818404149015171561412e57613f259161446c565b61013954158015906150a65790565b5061013a54151590565b919061010083820312613e9657825192602081015192613f25604083015193608060608501519401614c87565b6150ec6150f591610137613f5a565b50918254614121565b9055614ea8610131918254614121565b9190604083820312613e9657825192602090818101519067ffffffffffffffff8211613e9657019180601f84011215613e96578251615143816140a0565b936151516040519586613f76565b818552838086019260051b820101928311613e96578301905b828210615178575050505090565b8151815290830190830161516a565b82826151929261477b565b906000821315614fb057613f25926151a991614874565b9061446c565b610229546040516370a0823160e01b81526001600160a01b0392831660048201529160209183916024918391165afa90811561463c576000916151f0575090565b90506020813d602011615217575b8161520b60209383613f76565b81010312613e96575190565b3d91506151fe565b60ff61014b5460081c1661522f57565b604051631ca61d7760e01b8152600490fd5b60ff61014b5460101c1615918261526d575b505061525b57565b604051636f97b88360e01b8152600490fd5b6001600160a01b039182169116141590503880615253565b3d156152b0573d9061529682613fae565b916152a46040519384613f76565b82523d6000602084013e565b606090565b61014f546001600160a01b0393926000918516803b1561080e57604051630155ee3160e01b815291600a811015615355576044838593819360048301523460248301525afa801561534a5761533a575b5080808093953490615315614908565b165af1615320615285565b501561532857565b6040516312171d8360e31b8152600490fd5b8161534491613f76565b38615305565b6040513d84823e3d90fd5b634e487b7160e01b84526021600452602484fd5b61409e9061014e61537b828254614375565b905561022954309033906001600160a01b0316615ac1565b919061539e906146ff565b9190926153ab8385614de2565b90808211156153b8575050565b6044925060405191637912120160e01b835260048301526024820152fd5b9093926000926000956153e7614151565b96936001600160a01b0391859190831680615615575b5061012f54604051636eb1769f60e11b81526001600160a01b038316600482015230602482015260209490918116908583604481855afa92831561560a578894939291879187946155d3575b50836154ab575b5050505050505086015115615467575b5050509190565b9091925061547f670de0b6b3a7640000928392614543565b048085529082156154a35761549b920490816040860152614375565b388080615460565b50905061549b565b8d896154bb836101305416615818565b9890986154cc575b97505050615450565b670de0b6b3a76400006154f06154e68b936154f695614543565b6101435490614543565b0461446c565b81840181815297908d9081156155c85750916155176060926155239461446c565b91829101528751614375565b80945b10948515615555575b5050505050615546575b80808085818d898b6154c3565b81905260608801523880615539565b6040516370a0823160e01b81529116600482015292935090829060249082905afa9081156155bd578491615590575b5010388085818061552f565b90508481813d83116155b6575b6155a78183613f76565b81010312610a41575138615584565b503d61559d565b6040513d86823e3d90fd5b925050508094615526565b92935093945081813d8311615603575b6155ed8183613f76565b81010312610b2f57908588949392519238615449565b503d6155e3565b6040513d87823e3d90fd5b9095506020836101c35416916024604051809481936364a731e960e01b835260048301525afa801561534a57829061565a575b615653915084614543565b94386153fd565b506020813d602011615686575b8161567460209383613f76565b81010312610615576156539051615648565b3d9150615667565b9261409e94919293825115156000146156fe575060406156f9926156f1670de0b6b3a76400006156c361013b54845190614543565b046101316156d2828254614375565b90556156eb60018060a01b036101465416918451614121565b90614556565b015190614556565b614556565b9060606156f99361572060018060a01b03610146541660208301519086615b79565b015191615b79565b803b1561576f577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b03909216919091179055565b60405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b602081519101805192670de0b6b3a76400009384039084821161412e576157f76146e99261473295614543565b9251614543565b9190826040910312613e9657613f25602083519301614144565b604080516359e02dd760e01b81529291839060049082906001600160a01b03165afa91821561463c5760009060009361585057509190565b905061587591925060403d604011615879575b61586d8183613f76565b8101906157fe565b9091565b503d615863565b61588c81610137613f5a565b505490670de0b6b3a76400009182810292818404149015171561412e57613f25926158cc6158bf6147b293610151613e54565b90549060031b1c8461446c565b9261446c565b61015254604080516359e02dd760e01b80825293929091906001600160a01b039081168284600481845afa80156159c4576000946000916159a1575b501561598a575061015354169080519485528085600481855afa801561597f5760009560009161595c575b50156159455750509190565b6024925051906305e8989360e11b82526004820152fd5b9050816159769296503d87116158795761586d8183613f76565b94909438615939565b50513d6000823e3d90fd5b6024908351906305e8989360e11b82526004820152fd5b90506159bb919450833d85116158795761586d8183613f76565b9390933861590e565b83513d6000823e3d90fd5b602091615a32916001600160a01b03166000806159eb86613fae565b936159f96040519586613f76565b8685527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656487860152868151910182855af16149f2615285565b8051828115918215615aa2575b5050905015615a4b5750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b8380929350010312613e965781615ab99101614144565b808238615a3f565b6040516323b872dd60e01b60208201526001600160a01b03928316602482015292909116604483015260648083019390935291815261409e916145a8608483613f76565b6040516340c10f1960e01b81526001600160a01b039283166004820152602481019390935260209183916044918391600091165af1801561463c57615b475750565b6020813d602011615b71575b81615b6060209383613f76565b81010312613e9657614bf690614144565b3d9150615b53565b919081615b8557505050565b61012f5461409e93906001600160a01b0316615ac1565b91929015615bfe5750815115615bb0575090565b3b15615bb95790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015615c115750805190602001fd5b6040519062461bcd60e51b82528160208060048301528251908160248401526000935b828510615c57575050604492506000838284010152601f80199101168101030190fd5b8481018201518686016044015293810193859350615c34565b61015454156150155780615c826158d2565b919093615c8f6000614eea565b9401938291615d28575b019360008512615d1f57845b840391818511615ce7575050818111615cc957505061015555610156554261015755565b60449250604051916306da41e560e11b835260048301526024820152fd5b9080859211615d0d57604491604051916306da41e560e11b835260048301526024820152fd5b604051630fb4fd3560e11b8152600490fd5b84600003615ca5565b90508160000390615c99565b6001600160a01b0316803b15613e9657604051632770a7eb60e21b815230600482015260248101929092526000908290604490829084905af1801561463c57615d7a5750565b600061409e91613f7656fea26469706673582212203df412547bddfa4178b48a0f8e6f363ef64a0bdf26c90f5592ff40ed805f329e64736f6c63430008180033","name":"MocCARC20","is_blueprint":false,"license_type":"none","is_fully_verified":false,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"london","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"project/contracts/providers/DataProvider.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { IDataProvider } from \"moc-main-latest/contracts/interfaces/IDataProvider.sol\";\n\n/**\n * @title DataProvider\n * @notice Allows the Owner, to set the value so that the protocol could peek it.\n */\ncontract DataProvider is Ownable, IDataProvider {\n    bytes32 public data;\n\n    constructor(address owner_, uint256 initialData_) Ownable() {\n        _transferOwnership(owner_);\n        data = bytes32(initialData_);\n    }\n\n    function peek() external view returns (bytes32, bool) {\n        return (data, true);\n    }\n\n    function poke(uint256 data_) external onlyOwner {\n        data = bytes32(data_);\n    }\n\n    function getLastPublicationBlock() external view returns (uint256) {\n        return block.number;\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeaconUpgradeable.sol\";\nimport \"../../interfaces/IERC1967Upgradeable.sol\";\nimport \"../../interfaces/draft-IERC1822Upgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/StorageSlotUpgradeable.sol\";\nimport \"../utils/Initializable.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n */\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\n    function __ERC1967Upgrade_init() internal onlyInitializing {\n    }\n\n    function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\n    }\n    // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n    bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _getImplementation() internal view returns (address) {\n        return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        require(AddressUpgradeable.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n        StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Perform implementation upgrade\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeTo(address newImplementation) internal {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n    }\n\n    /**\n     * @dev Perform implementation upgrade with additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\n        _upgradeTo(newImplementation);\n        if (data.length > 0 || forceCall) {\n            AddressUpgradeable.functionDelegateCall(newImplementation, data);\n        }\n    }\n\n    /**\n     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\n        // Upgrades from old implementations will perform a rollback test. This test requires the new\n        // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n        // this special case will break upgrade paths from old UUPS implementation to new ones.\n        if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\n            _setImplementation(newImplementation);\n        } else {\n            try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n                require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n            } catch {\n                revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n            }\n            _upgradeToAndCall(newImplementation, data, forceCall);\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _getAdmin() internal view returns (address) {\n        return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n        StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     */\n    function _changeAdmin(address newAdmin) internal {\n        emit AdminChanged(_getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n     */\n    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function _getBeacon() internal view returns (address) {\n        return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the EIP1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        require(AddressUpgradeable.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n        require(\n            AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\n            \"ERC1967: beacon implementation is not a contract\"\n        );\n        StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n    }\n\n    /**\n     * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n     *\n     * Emits a {BeaconUpgraded} event.\n     */\n    function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\n        _setBeacon(newBeacon);\n        emit BeaconUpgraded(newBeacon);\n        if (data.length > 0 || forceCall) {\n            AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\n        }\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/security/ReentrancyGuard.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    constructor() {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be _NOT_ENTERED\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _status == _ENTERED;\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/token/ERC20/IERC20Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/utils/introspection/ERC165Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n    function __ERC165_init() internal onlyInitializing {\n    }\n\n    function __ERC165_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165Upgradeable).interfaceId;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/auxiliary/CommissionSplitterRC20.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { CommissionSplitterBase } from \"./CommissionSplitterBase.sol\";\n\n/**\n  @dev Contract that split his balance between two addresses based on a\n  proportion defined by Governance.\n */\ncontract CommissionSplitterRC20 is CommissionSplitterBase {\n    // ------- Storage -------\n\n    // collateral asset\n    IERC20 public acToken;\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    // ------- Initializer -------\n\n    /**\n     * @notice contract initializer\n     * @param acToken_ collateral asset contract. Address(0) for coinbase\n     * @param governorAddress_ governor address\n     * @param feeToken_ fee token contract\n     * @param acTokenAddressRecipient1_ address who receives acTokenPctToRecipient1\n     * @param acTokenAddressRecipient2_ address who receives (100% - acTokenPctToRecipient1)\n     * @param acTokenPctToRecipient1_ percentage of the acToken balance to send to acTokenAddressRecipient1 [PREC]\n     * @param feeTokenAddressRecipient1_ address who receives feeTokenPctToRecipient1\n     * @param feeTokenAddressRecipient2_ address who receives (100% - feeTokenPctToRecipient1)\n     * @param feeTokenPctToRecipient1_ percentage of the feeToken balance to send to acTokenAddressRecipient1 [PREC]\n     */\n    // slither-disable missing-zero-check\n    function initialize(\n        IERC20 acToken_,\n        address governorAddress_,\n        IERC20 feeToken_,\n        address acTokenAddressRecipient1_,\n        address acTokenAddressRecipient2_,\n        uint256 acTokenPctToRecipient1_,\n        address feeTokenAddressRecipient1_,\n        address feeTokenAddressRecipient2_,\n        uint256 feeTokenPctToRecipient1_\n    ) external initializer {\n        acToken = acToken_;\n        __CommissionSplitter_init(\n            governorAddress_,\n            feeToken_,\n            acTokenAddressRecipient1_,\n            acTokenAddressRecipient2_,\n            acTokenPctToRecipient1_,\n            feeTokenAddressRecipient1_,\n            feeTokenAddressRecipient2_,\n            feeTokenPctToRecipient1_\n        );\n    }\n\n    // ------- Internal Functions -------\n\n    /**\n     * @notice get the AC balance of the contract\n     * @return balance of the contract\n     */\n    function _acBalanceOfSelf() internal view override returns (uint256) {\n        return acToken.balanceOf(address(this));\n    }\n\n    /**\n     * @notice transfers AC to a recipient\n     * @param recipient_ recipient address\n     * @param amount_ amount to transfer\n     */\n    function _acTransfer(address recipient_, uint256 amount_) internal override {\n        SafeERC20.safeTransfer(acToken, recipient_, amount_);\n    }\n\n    // ------- Only Authorized Changer Functions -------\n\n    /** @notice sets new AC token. Address(0) for coinbase\n     * @param newAcToken_ new AC token contract. Address(0) for coinbase\n     */\n    function setAcToken(IERC20 newAcToken_) external onlyAuthorizedChanger {\n        acToken = newAcToken_;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"project/contracts/token/USDRIF/MocRC20.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IMocRC20 } from \"moc-main-latest/contracts/interfaces/IMocRC20.sol\";\nimport { IGovernor, Governed } from \"./Governed.sol\";\n/* solhint-disable-next-line max-line-length */\nimport { AccessControlEnumerableUpgradeable, AccessControlUpgradeable, IAccessControlUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport { ERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\nimport { UUPSUpgradeable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\n\n/**\n * @title MocRC20\n * @notice Base Moc ERC20 Token: burn, mint. It can be both Pegs and Collateral Tokens.\n * @dev ERC20 like token that allows roles allowed contracts to mint and burn (destroyed) any token.\n */\ncontract MocRC20 is IMocRC20, AccessControlEnumerableUpgradeable, ERC20Upgradeable, UUPSUpgradeable, Governed {\n    bytes32 private constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n    bytes32 private constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n    error NotUniqueRole(bytes32 role);\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    /**\n     * See {__MocRC20_init}.\n     */\n    function initialize(\n        string memory name_,\n        string memory symbol_,\n        address admin_,\n        IGovernor governor_\n    ) external virtual initializer {\n        __MocRC20_init(name_, symbol_, admin_, governor_);\n        _grantRole(MINTER_ROLE, admin_);\n        _grantRole(BURNER_ROLE, admin_);\n    }\n\n    /**\n     * @dev Grants `DEFAULT_ADMIN_ROLE` to `admin` address.\n     *\n     * See {ERC20_init}.\n     */\n    function __MocRC20_init(\n        string memory name_,\n        string memory symbol_,\n        address admin_,\n        IGovernor governor_\n    ) internal onlyInitializing {\n        __ERC20_init(name_, symbol_);\n        __AccessControlEnumerable_init();\n        __UUPSUpgradeable_init();\n        __Governed_init(address(governor_));\n        _grantRole(DEFAULT_ADMIN_ROLE, admin_);\n    }\n\n    /**\n     * @inheritdoc UUPSUpgradeable\n     * @dev checks that the changer that will do the upgrade is currently authorized by governance to makes\n     * changes within the system\n     * @param newImplementation new implementation contract address(not used)\n     */\n    /* solhint-disable-next-line no-empty-blocks */\n    function _authorizeUpgrade(address newImplementation) internal override onlyAuthorizedChanger {}\n\n    /**\n     * @dev Creates `amount` new tokens for `to`.\n     * See {ERC20-_mint}.\n     *\n     * Requirements:\n     *\n     * - the caller must have the `MINTER_ROLE`.\n     */\n    function mint(address to, uint256 amount) external virtual onlyRole(MINTER_ROLE) returns (bool) {\n        _mint(to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Burns a specific `amount` of tokens for `to`.\n     * * See {ERC20-_burn}.\n     * Requirements:\n     *\n     * - the caller must have the `BURNER_ROLE`.\n     */\n    function burn(address to, uint256 amount) external virtual onlyRole(BURNER_ROLE) {\n        _burn(to, amount);\n    }\n\n    /**\n     * @dev Grants all `roles` to `account` while sender renounces to all ``role``\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     * - no one else must have any other role\n     *\n     * May emit a {RoleGranted x3, RoleRevoked x3} event.\n     */\n    function transferAllRoles(address account) public virtual onlyRole(getRoleAdmin(DEFAULT_ADMIN_ROLE)) {\n        _grantRole(DEFAULT_ADMIN_ROLE, account);\n        _grantRole(MINTER_ROLE, account);\n        _grantRole(BURNER_ROLE, account);\n        _revokeRole(MINTER_ROLE, msg.sender);\n        _revokeRole(BURNER_ROLE, msg.sender);\n        _revokeRole(DEFAULT_ADMIN_ROLE, msg.sender);\n        // One the new admin account has roles\n        if (getRoleMemberCount(DEFAULT_ADMIN_ROLE) != 1) revert NotUniqueRole(DEFAULT_ADMIN_ROLE);\n        if (getRoleMemberCount(MINTER_ROLE) != 1) revert NotUniqueRole(MINTER_ROLE);\n        if (getRoleMemberCount(BURNER_ROLE) != 1) revert NotUniqueRole(BURNER_ROLE);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role  OR\n     *   the caller must have be an authorized Governance changer.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(\n        bytes32 role,\n        address account\n    ) public virtual override(AccessControlUpgradeable, IAccessControlUpgradeable) {\n        verifyRoleManagementPrivilege(role);\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role  OR\n     *   the caller must have be an authorized Governance changer.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(\n        bytes32 role,\n        address account\n    ) public virtual override(AccessControlUpgradeable, IAccessControlUpgradeable) {\n        verifyRoleManagementPrivilege(role);\n        _revokeRole(role, account);\n    }\n\n    // ------- Internal Functions -------\n\n    function verifyRoleManagementPrivilege(bytes32 role) private view {\n        if (!governor.isAuthorizedChanger(msg.sender) && !hasRole(getRoleAdmin(role), msg.sender))\n            revert NotAuthorizedChanger();\n    }\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/multiCollateral/MocMultiCollateralBase.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocUpgradable } from \"../governance/MocUpgradable.sol\";\nimport { MocOperations } from \"../core/MocOperations.sol\";\nimport { IMocSwapper } from \"../interfaces/IMocSwapper.sol\";\nimport { IPriceProvider } from \"../interfaces/IPriceProvider.sol\";\n/* solhint-disable-next-line max-line-length */\nimport { ReentrancyGuardUpgradeable } from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\n\n// ------- External Structs -------\n\nstruct BucketParams {\n    // bucket AC to coinbase price provider. Not used for coinbase bucket\n    IPriceProvider acCoinbasePriceProvider;\n    // bucket rebalance execution fee recipient. Not used for coinbase bucket\n    address rebalanceExecFeeRecipient;\n    // target coverage to reach during a micro liquidation [PREC]\n    uint256 rtcThrld;\n    // threshold to trigger the micro liquidation [PREC]\n    uint256 microLiquidationThrld;\n    // additional pct of AC sent to the target bucket during a micro liquidation [PREC]\n    uint256 penaltyRate;\n}\n\n/**\n * @title MocMultiCollateralBase\n *\n */\nabstract contract MocMultiCollateralBase is MocUpgradable, ReentrancyGuardUpgradeable {\n    // ------- Custom Errors -------\n    error BucketAlreadyExists();\n    error BucketDoesNotExist();\n    error InvalidParams();\n    // ------- Events -------\n    event BucketChange(\n        uint256 bucketIndex_,\n        address indexed bucket_,\n        BucketParams bucketParams_,\n        IMocSwapper[] mocSwappers\n    );\n\n    // ------- Structs -------\n    struct BucketIndex {\n        // bucket index\n        uint240 index;\n        // true if bucket exists\n        bool exists;\n        // true if bucket is liquidated, queue can be executed to empty all the the operations and return locked funds\n        bool liquidated;\n    }\n\n    // ------- Storage -------\n    // bucket index 0 is considered the base bucket and used to calculate the normalization factor\n    MocOperations[] public buckets;\n    // bucket indexes\n    mapping(MocOperations => BucketIndex) public bucketIndex;\n\n    // ------- Internal Functions -------\n    /**\n     * @notice set rebalance params. Used when a bucket is added or edited\n     * @param bucket_ address of the mocOperations implementation to interact with\n     * @param params_ params of bucket to add or edit:\n     *      acCoinbasePriceProvider bucket AC to coinbase price provider. Not used for coinbase bucket\n     *      rebalanceExecFeeRecipient bucket rebalance execution fee recipient. Not used for coinbase bucket\n     *      rtcThrld target coverage to reach during a micro liquidation [PREC]\n     *      microLiquidationThrld threshold to trigger the micro liquidation [PREC]\n     *      penaltyRate additional pct of AC sent to the target bucket during a micro liquidation [PREC]\n     * @param mocSwappers_ MocSwapper contracts for the originBucketAC / targetBucketAC pool\n     */\n    function _setRebalanceParams(\n        MocOperations bucket_,\n        BucketParams calldata params_,\n        IMocSwapper[] memory mocSwappers_\n    ) internal virtual;\n\n    /**\n     * @notice If time, updates the EMA for all the Pegged Token prices for all the buckets.\n     * @param buckets_ buckets array\n     */\n    function _updatesCtargemaCA(MocOperations[] memory buckets_) internal {\n        for (uint256 j = 0; j < buckets_.length; j = unchecked_inc(j)) {\n            buckets_[j].updateEmas();\n        }\n    }\n\n    // ------- Only Authorized Functions -------\n\n    /**\n     * @notice adds a new bucket\n     * @param bucket_ address of the mocOperations implementation to interact with\n     * @param params_ params of bucket to add:\n     *      acCoinbasePriceProvider bucket AC to coinbase price provider\n     *      rtcThrld target coverage to reach during a micro liquidation [PREC]\n     *      microLiquidationThrld threshold to trigger the micro liquidation [PREC]\n     *      penaltyRate additional pct of AC sent to the target bucket during a micro liquidation [PREC]\n     * @param mocSwappers_ MocSwapper contracts for the originBucketAC / targetBucketAC pool\n     *\n     * @dev buckets should be added using the corresponding changer template, which\n     *      should guarantee bucket is not already part of the solution and all its\n     *      TPs exists on base bucket (normalization precondition)\n     */\n    function addBucket(\n        MocOperations bucket_,\n        BucketParams calldata params_,\n        IMocSwapper[] calldata mocSwappers_\n    ) external onlyAuthorizedChanger {\n        if (bucketIndex[bucket_].exists || bucketIndex[bucket_].liquidated) revert BucketAlreadyExists();\n        uint256 bucketsAmount = buckets.length;\n        if (mocSwappers_.length != bucketsAmount) revert InvalidParams();\n\n        uint240 newBucketIndex = uint240(bucketsAmount);\n        bucketIndex[bucket_] = BucketIndex({ index: newBucketIndex, exists: true, liquidated: false });\n\n        _setRebalanceParams(bucket_, params_, mocSwappers_);\n\n        buckets.push(bucket_);\n\n        emit BucketChange(newBucketIndex, address(bucket_), params_, mocSwappers_);\n    }\n\n    /**\n     * @notice modifies a bucket\n     * @param bucket_ address of the mocOperations implementation to interact with\n     * @param params_ params of bucket to edit:\n     *      acCoinbasePriceProvider bucket AC to coinbase price provider. Not used for coinbase bucket\n     *      rebalanceExecFeeRecipient bucket rebalance execution fee recipient. Not used for coinbase bucket\n     *      rtcThrld target coverage to reach during a micro liquidation [PREC]\n     *      microLiquidationThrld threshold to trigger the micro liquidation [PREC]\n     *      penaltyRate additional pct of AC sent to the target bucket during a micro liquidation [PREC]\n     */\n    function editBucket(MocOperations bucket_, BucketParams calldata params_) external onlyAuthorizedChanger {\n        BucketIndex memory iBucket = bucketIndex[bucket_];\n        if (!iBucket.exists) revert BucketDoesNotExist();\n\n        IMocSwapper[] memory mocSwappers; // empty array, MocSwappers are edited using an specific setter\n        _setRebalanceParams(bucket_, params_, mocSwappers);\n\n        emit BucketChange(iBucket.index, address(bucket_), params_, mocSwappers);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/BasefeeProvider.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IPriceProvider } from \"@moc/moc-main/contracts/interfaces/IPriceProvider.sol\";\n\ncontract BasefeeProvider is IPriceProvider {\n    function peek() external view returns (bytes32 price, bool valid) {\n        return (bytes32(uint256(block.basefee)), true);\n    }\n\n    function getLastPublicationBlock() external view returns (uint256 lastPublicationBlock) {\n        return block.number;\n    }\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/auxiliary/MocReverseAuction.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { Governed, IGovernor } from \"../governance/Governed.sol\";\nimport { IMocSwapper } from \"../interfaces/IMocSwapper.sol\";\nimport { IPriceProvider } from \"../interfaces/IPriceProvider.sol\";\nimport { ReentrancyGuard } from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\n/**\n * @title MocReverseAuction\n * @notice This contract accumulates tokens, swaps them for a different token,\n *  and transfers the resulting tokens to a specified address.\n */\ncontract MocReverseAuction is Governed, ReentrancyGuard {\n    address private constant COINBASE = address(0);\n    // ------- Events -------\n    event EmergencyWithdraw(address token_, address to_, uint256 amount_);\n    event Triggered(address tokenIn_, address tokenOut_, uint256 amountIn_, uint256 amountOut_, address outputAccount_);\n    // ------- Custom Errors -------\n    error NotCoinbase();\n    error TransferFailed();\n    error InvalidSlippage();\n\n    // ------- Storage -------\n    // MocSwapper contract used to swap the tokens\n    IMocSwapper public mocSwapper;\n    // token to accumulate and swap\n    address public tokenIn;\n    // token to receive in the swap\n    address public tokenOut;\n    // address who receives the swapped token\n    address public outputAccount;\n    // minimum amount of tokenIn that justifies trigger exchange orders\n    uint256 public orderThreshold;\n    // tokenIn/tokenOut price provider used to compute amountOutMin\n    IPriceProvider public priceProvider;\n    // slippage as a percentage with 18 decimals. 1 * 1e18 means 100%.\n    uint256 public slippage;\n\n    /**\n     * @notice constructor\n     * @param governor_ address of the governor contract\n     * @param mocSwapper_ address of the MocSwapper contract\n     * @param tokenIn_ token to accumulate and swap\n     * @param tokenOut_ token to receive in the swap\n     * @param outputAccount_ address who receives the swapped token\n     * @param orderThreshold_ minimum amount of tokenIn that justifies trigger exchange orders\n     */\n    constructor(\n        address governor_,\n        address mocSwapper_,\n        address tokenIn_,\n        address tokenOut_,\n        address outputAccount_,\n        uint256 orderThreshold_,\n        address priceProvider_,\n        uint256 slippage_\n    ) {\n        _disableInitializers();\n        governor = IGovernor(governor_);\n        mocSwapper = IMocSwapper(mocSwapper_);\n        tokenIn = tokenIn_;\n        tokenOut = tokenOut_;\n        outputAccount = outputAccount_;\n        orderThreshold = orderThreshold_;\n        priceProvider = IPriceProvider(priceProvider_);\n        _setSlippage(slippage_);\n    }\n\n    /**\n     *@notice transfer tokens to the given address\n     *@param token_ address of the token to be transferred\n     *@param to_ address of the recipient\n     *@param amount_ amount of tokens to be transferred\n     */\n    function _transfer(address token_, address to_, uint256 amount_) internal {\n        if (amount_ > 0 && to_ != address(0)) {\n            if (token_ == COINBASE) {\n                // solhint-disable-next-line avoid-low-level-calls\n                (bool success, ) = to_.call{ value: amount_ }(\"\");\n                if (!success) revert TransferFailed();\n            } else {\n                SafeERC20.safeTransfer(IERC20(token_), to_, amount_);\n            }\n        }\n    }\n\n    /**\n     * @notice get the balance of the contract\n     * @param token_ address of the token\n     * @return balance of the contract\n     */\n    function _balanceOfSelf(address token_) internal view returns (uint256) {\n        if (token_ == COINBASE) {\n            return address(this).balance;\n        } else {\n            return IERC20(token_).balanceOf(address(this));\n        }\n    }\n\n    /**\n     * @notice get the balance of the contract\n     * @return balance of the contract\n     */\n    function balanceOfSelf() external view returns (uint256) {\n        return _balanceOfSelf(tokenIn);\n    }\n\n    /**\n     * @notice trigger an order to swap tokens and send them to the outputAccount\n     * @dev it will swap up to the maximum amount allowed by the MocSwapper,\n     *  or the contract’s full balance if it is lower\n     */\n    function triggerOrders() external nonReentrant {\n        IMocSwapper _mocSwapper = mocSwapper;\n        address _outputAccount = outputAccount;\n\n        address _tokenIn = tokenIn;\n        address _tokenOut = tokenOut;\n\n        (uint256 amountIn, uint256 amountOutMin) = _getAmountOutMin();\n        uint256 amountOut;\n\n        if (_tokenIn == COINBASE) {\n            amountOut = _mocSwapper.swapCoinbase{ value: amountIn }(_tokenOut, amountOutMin, _outputAccount);\n        } else {\n            SafeERC20.forceApprove(IERC20(_tokenIn), address(_mocSwapper), amountIn);\n            amountOut = _mocSwapper.swapRC20(_tokenIn, _tokenOut, amountIn, amountOutMin, _outputAccount);\n        }\n        emit Triggered(_tokenIn, _tokenOut, amountIn, amountOut, _outputAccount);\n    }\n\n    /**\n     * @notice Returns `true` if there is enough tokenIn to justify exchange orders\n     * @dev triggerOrders should only be called when this function returns true but it is not enforced\n     **/\n    function readyToTriggerOrders() external view returns (bool) {\n        return (_balanceOfSelf(tokenIn) >= orderThreshold);\n    }\n\n    /**\n     * @notice returns the amountIn and amountOutMin for a swap\n     * @return amountIn amount of tokenIn to swap\n     * @return amountOutMin minimum amount of tokenOut expected\n     */\n    function getAmountOutMin() external view returns (uint256 amountIn, uint256 amountOutMin) {\n        return _getAmountOutMin();\n    }\n\n    // ------- Only Authorized Changer Functions -------\n\n    /**\n     * @notice withdraws the entire balance of the contract to the given address\n     * @dev only the authorized changer can call this function\n     * @param token_ address of the token to be withdrawn\n     * @param to_ address of the recipient\n     */\n    function emergencyWithdraw(address token_, address to_) external onlyAuthorizedChanger {\n        uint256 balance = _balanceOfSelf(token_);\n        _transfer(token_, to_, balance);\n        emit EmergencyWithdraw(token_, to_, balance);\n    }\n\n    /**\n     * @notice sets a new MocSwapper\n     * @dev only the authorized changer can call this function\n     * @param mocSwapper_ address of the MocSwapper contract\n     */\n    function setMocSwapper(address mocSwapper_) external onlyAuthorizedChanger {\n        mocSwapper = IMocSwapper(mocSwapper_);\n    }\n\n    /**\n     * @notice sets a new tokenIn\n     * @dev only the authorized changer can call this function\n     * @param tokenIn_ address of the token\n     */\n    function setTokenIn(address tokenIn_) external onlyAuthorizedChanger {\n        tokenIn = tokenIn_;\n    }\n\n    /**\n     * @notice sets a new tokenOut\n     * @dev only the authorized changer can call this function\n     * @param tokenOut_ address of the token\n     */\n    function setTokenOut(address tokenOut_) external onlyAuthorizedChanger {\n        tokenOut = tokenOut_;\n    }\n\n    /**\n     * @notice sets a new outputAccount\n     * @dev only the authorized changer can call this function\n     * @param outputAccount_ address of the output account\n     */\n    function setOutputAccount(address outputAccount_) external onlyAuthorizedChanger {\n        outputAccount = outputAccount_;\n    }\n\n    /**\n     * @notice sets a new orderThreshold\n     * @dev only the authorized changer can call this function\n     * @param orderThreshold_ new minimum amount of tokenIn that justifies trigger exchange orders\n     */\n    function setOrderThreshold(uint256 orderThreshold_) external onlyAuthorizedChanger {\n        orderThreshold = orderThreshold_;\n    }\n\n    /**\n     * @notice sets a new price provider\n     * @dev only the authorized changer can call this function\n     * @param priceProvider_ address of the price provider\n     */\n    function setPriceProvider(address priceProvider_) external onlyAuthorizedChanger {\n        priceProvider = IPriceProvider(priceProvider_);\n    }\n\n    /**\n     * @notice sets a new slippage value\n     * @dev only the authorized changer can call this function\n     * @param slippage_ new slippage value, 0.05 * 1e18 means 5%\n     */\n    function setSlippage(uint256 slippage_) external onlyAuthorizedChanger {\n        _setSlippage(slippage_);\n    }\n\n    function _setSlippage(uint256 slippage_) internal {\n        if (slippage_ > PRECISION) revert InvalidSlippage();\n        slippage = slippage_;\n    }\n\n    function _getAmountOutMin() internal view returns (uint256 amountIn, uint256 amountOutMin) {\n        IPriceProvider _priceProvider = priceProvider;\n        (bytes32 price, ) = _priceProvider.peek();\n\n        address _tokenIn = tokenIn;\n        address _tokenOut = tokenOut;\n        uint256 maxAmountToSwap = mocSwapper.getSafeMaxAmountToSwap(_tokenIn, _tokenOut);\n        amountIn = Math.min(maxAmountToSwap, _balanceOfSelf(_tokenIn));\n        amountOutMin = (amountIn * uint256(price)) / PRECISION;\n        amountOutMin = (amountOutMin * (PRECISION - slippage)) / PRECISION;\n    }\n\n    // @notice used to receive coinbase\n    // solhint-disable-next-line no-empty-blocks\n    receive() external payable {\n        if (tokenIn != COINBASE) revert NotCoinbase();\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/interfaces/draft-IERC1822Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822ProxiableUpgradeable {\n    /**\n     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n     * address.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy.\n     */\n    function proxiableUUID() external view returns (bytes32);\n}\n"},{"file_path":"project/contracts/changers/fixInfinityAndDOCRName/FixInfinityAndDOCRNameChanger.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IChangeContract } from \"moc-main-latest/contracts/interfaces/IChangeContract.sol\";\nimport { MocCARC20 } from \"moc-main-latest/contracts/collateral/rc20/MocCARC20.sol\";\n\n/**\n  @title FixInfinityAndDOCRNameChanger\n  @notice Sets DOC bucket time spans to `type(uint256).max / 2` to represent infinity safely\n */\ncontract FixInfinityAndDOCRNameChanger is IChangeContract {\n    uint256 public constant HALF_INFINITY = type(uint256).max / 2;\n\n    MocCARC20 public immutable docBucket;\n\n    constructor(MocCARC20 docBucket_) {\n        docBucket = docBucket_;\n    }\n\n    function execute() external {\n        docBucket.setTCInterestParams(\n            docBucket.tcInterestCollectorAddress(),\n            docBucket.tcInterestRate(),\n            HALF_INFINITY\n        );\n        docBucket.setSettlementTimeSpan(HALF_INFINITY);\n        docBucket.setEmaCalculationTimeSpan(HALF_INFINITY);\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/proxy/beacon/IBeaconUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeaconUpgradeable {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {BeaconProxy} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/queue/MocQueue.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocQueueExecFees } from \"./MocQueueExecFees.sol\";\nimport { MocCore } from \"../core/MocCore.sol\";\nimport { MocCommons } from \"../core/MocCommons.sol\";\nimport { MocBaseBucket } from \"../core/MocBaseBucket.sol\";\nimport { MocOperations } from \"../core/MocOperations.sol\";\nimport { MocMultiCollateralGuard } from \"../multiCollateral/MocMultiCollateralGuard.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\n/**\n * @title MocQueue: Allows queue Operation deferral execution processing\n */\ncontract MocQueue is MocQueueExecFees {\n    // ------- Custom Errors -------\n    error BucketAlreadyRegistered();\n    error NotMocBucket();\n    error NotMocMultiCollateralGuard();\n\n    // ------- Errors Strings -------\n    string private constant LOW_COVERAGE = \"Low coverage\";\n    string private constant INSUFFICIENT_AC_SENT = \"Insufficient qac sent\";\n    string private constant INSUFFICIENT_TP_SENT = \"Insufficient tp sent\";\n    string private constant INSUFFICIENT_TC_SENT = \"Insufficient tc sent\";\n    string private constant INSUFFICIENT_TC_TO_REDEEM = \"Insufficient tc to redeem\";\n    string private constant INSUFFICIENT_TP_TO_MINT = \"Insufficient tp to mint\";\n    string private constant AC_BELOW_MINIMUM = \"qAC below minimum required\";\n    string private constant TC_BELOW_MINIMUM = \"qTc below minimum required\";\n    string private constant TP_BELOW_MINIMUM = \"qTp below minimum required\";\n    string private constant FLUX_CAPACITOR = \"Max flux capacitor operation reached\";\n\n    // ------- Events -------\n    event OperationError(uint256 operId_, bytes4 errorCode_, string msg_);\n    event UnhandledError(uint256 operId_, bytes reason_);\n    event ACUnlockFailed(uint256 operId_, address indexed sender_, uint256 qAC_);\n\n    event OperationQueued(address indexed bucket_, uint256 operId_, OperType operType_);\n    event OperationExecuted(address indexed executor, uint256 indexed operId_);\n\n    event TCMinted(\n        address indexed sender_,\n        address indexed recipient_,\n        uint256 qTC_,\n        uint256 qAC_,\n        uint256 qACfee_,\n        uint256 qFeeToken_,\n        uint256 qACVendorMarkup_,\n        uint256 qFeeTokenVendorMarkup_,\n        address vendor_,\n        uint256 operId_\n    );\n    event TCRedeemed(\n        address indexed sender_,\n        address indexed recipient_,\n        uint256 qTC_,\n        uint256 qAC_,\n        uint256 qACfee_,\n        uint256 qFeeToken_,\n        uint256 qACVendorMarkup_,\n        uint256 qFeeTokenVendorMarkup_,\n        address vendor_,\n        uint256 operId_\n    );\n    event TPMinted(\n        address indexed tp_,\n        address indexed sender_,\n        address indexed recipient_,\n        uint256 qTP_,\n        uint256 qAC_,\n        uint256 qACfee_,\n        uint256 qFeeToken_,\n        uint256 qACVendorMarkup_,\n        uint256 qFeeTokenVendorMarkup_,\n        address vendor_,\n        uint256 operId_\n    );\n    event TPRedeemed(\n        address indexed tp_,\n        address indexed sender_,\n        address indexed recipient_,\n        uint256 qTP_,\n        uint256 qAC_,\n        uint256 qACfee_,\n        uint256 qFeeToken_,\n        uint256 qACVendorMarkup_,\n        uint256 qFeeTokenVendorMarkup_,\n        address vendor_,\n        uint256 operId_\n    );\n    event TCandTPRedeemed(\n        address indexed tp_,\n        address indexed sender_,\n        address indexed recipient_,\n        uint256 qTC_,\n        uint256 qTP_,\n        uint256 qAC_,\n        uint256 qACtoRedeemTC_,\n        uint256 qACtoRedeemTP_,\n        uint256 qACfee_,\n        uint256 qFeeToken_,\n        uint256 qACVendorMarkup_,\n        uint256 qFeeTokenVendorMarkup_,\n        address vendor_,\n        uint256 operId_\n    );\n    event TCandTPMinted(\n        address indexed tp_,\n        address indexed sender_,\n        address indexed recipient_,\n        uint256 qTC_,\n        uint256 qTP_,\n        uint256 qAC_,\n        uint256 qACtoMintTC_,\n        uint256 qACtoMintTP_,\n        uint256 qACfee_,\n        uint256 qFeeToken_,\n        uint256 qACVendorMarkup_,\n        uint256 qFeeTokenVendorMarkup_,\n        address vendor_,\n        uint256 operId_\n    );\n    event TPSwappedForTP(\n        address indexed tpFrom_,\n        address tpTo_,\n        address indexed sender_,\n        address indexed recipient_,\n        uint256 qTPfrom_,\n        uint256 qTPto_,\n        uint256 qACfee_,\n        uint256 qFeeToken_,\n        uint256 qACVendorMarkup_,\n        uint256 qFeeTokenVendorMarkup_,\n        address vendor_,\n        uint256 operId_\n    );\n    event TPSwappedForTC(\n        address indexed tp_,\n        address indexed sender_,\n        address indexed recipient_,\n        uint256 qTP_,\n        uint256 qTC_,\n        uint256 qACfee_,\n        uint256 qFeeToken_,\n        uint256 qACVendorMarkup_,\n        uint256 qFeeTokenVendorMarkup_,\n        address vendor_,\n        uint256 operId_\n    );\n    event TCSwappedForTP(\n        address indexed tp_,\n        address indexed sender_,\n        address indexed recipient_,\n        uint256 qTC_,\n        uint256 qTP_,\n        uint256 qACfee_,\n        uint256 qFeeToken_,\n        uint256 qACVendorMarkup_,\n        uint256 qFeeTokenVendorMarkup_,\n        address vendor_,\n        uint256 operId_\n    );\n\n    // ------- Structs -------\n    struct OperInfo {\n        // Operation Type\n        OperType operType;\n        // block number on which the Operation was queued\n        uint248 queuedBlk;\n    }\n\n    // ------- Storage -------\n\n    // mocOperations bucket that would be able to queue\n    MocOperations public mocOperations;\n    // Amount of Operations created\n    uint256 public operIdCount;\n    // first operation to be executed\n    uint256 public firstOperId;\n\n    mapping(uint256 => MocCore.MintTCParams) public operationsMintTC;\n    mapping(uint256 => MocCore.MintTPParams) public operationsMintTP;\n    mapping(uint256 => MocCore.RedeemTCParams) public operationsRedeemTC;\n    mapping(uint256 => MocCore.RedeemTPParams) public operationsRedeemTP;\n    mapping(uint256 => MocCore.MintTCandTPParams) public operationsMintTCandTP;\n    mapping(uint256 => MocCore.RedeemTCandTPParams) public operationsRedeemTCandTP;\n    mapping(uint256 => MocCore.SwapTCforTPParams) public operationsSwapTCforTP;\n    mapping(uint256 => MocCore.SwapTPforTCParams) public operationsSwapTPforTC;\n    mapping(uint256 => MocCore.SwapTPforTPParams) public operationsSwapTPforTP;\n\n    // OperId => Operation Type | block.number\n    mapping(uint256 => OperInfo) public opersInfo;\n\n    // min amount of blocks the Operation should wait in the Queue before execution\n    uint256 public minOperWaitingBlk;\n    // max amount of blocks the Operation should wait in the Queue. Even if there is no price update\n    // it can be executed after this amount of blocks\n    uint256 public maxOperWaitingBlk;\n    // track sender's locked funds on the bucket when they cannot be recovered after a failed operation\n    mapping(address sender => uint256 lockedFunds) public senderLockedFunds;\n    // total locked funds on the bucket when they cannot be recovered after a failed operation\n    uint256 public totalLockedFunds;\n\n    // ------- Modifiers -------\n    /// @notice functions with this modifier can be called only by MocMultiCollateralGuard contract\n    modifier onlyMocMultiCollateralGuard() {\n        if (msg.sender != address(mocMultiCollateralGuard)) revert NotMocMultiCollateralGuard();\n        _;\n    }\n\n    /// @notice functions with this modifier can be called only by Moc Bucket contract\n    modifier onlyMocBucket() {\n        if (msg.sender != address(mocOperations)) revert NotMocBucket();\n        _;\n    }\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    // ------- Initializer -------\n\n    function initialize(\n        address governor_,\n        address pauser_,\n        MocMultiCollateralGuard mocMultiCollateralGuard_,\n        uint256 minOperWaitingBlk_,\n        uint256 maxOperWaitingBlk_,\n        InitializeMocQueueExecCostsParams calldata mocQueueExecCostsParams_\n    ) external initializer {\n        if (minOperWaitingBlk_ > maxOperWaitingBlk_) revert InvalidValue();\n        __MocUpgradable_init(governor_, pauser_);\n        __MocQueueExecFees_init(mocQueueExecCostsParams_);\n        minOperWaitingBlk = minOperWaitingBlk_;\n        maxOperWaitingBlk = maxOperWaitingBlk_;\n        mocMultiCollateralGuard = mocMultiCollateralGuard_;\n    }\n\n    // ------- Internal Functions -------\n\n    /**\n     * @notice hook after mintedTC Operation execution, emits the TCMinted event\n     * @param operId_ Identifier to track the Operation lifecycle\n     * @param params_ TCMint params\n     * @param qACtotalNeeded_ amount of AC used to mint qTC\n     * @param feeCalcs_ platform fee detail breakdown\n     */\n    function _onDeferredTCMinted(\n        uint256 operId_,\n        MocCore.MintTCParams memory params_,\n        uint256 qACtotalNeeded_,\n        MocCore.FeeCalcs memory feeCalcs_\n    ) internal {\n        emit TCMinted(\n            params_.sender,\n            params_.recipient,\n            params_.qTC,\n            qACtotalNeeded_,\n            feeCalcs_.qACFee,\n            feeCalcs_.qFeeToken,\n            feeCalcs_.qACVendorMarkup,\n            feeCalcs_.qFeeTokenVendorMarkup,\n            params_.vendor,\n            operId_\n        );\n    }\n\n    /**\n     * @notice hook after redeemTC Operation execution, emits the TCRedeemed event\n     * @param operId_ Identifier to track the Operation lifecycle\n     * @param params_ mintTCto function params\n     * @param qACRedeemed_ amount of AC redeemed\n     * @param feeCalcs_ platform fee detail breakdown\n     */\n    function _onDeferredTCRedeemed(\n        uint256 operId_,\n        MocCore.RedeemTCParams memory params_,\n        uint256 qACRedeemed_,\n        MocCore.FeeCalcs memory feeCalcs_\n    ) internal {\n        emit TCRedeemed(\n            params_.sender,\n            params_.recipient,\n            params_.qTC,\n            qACRedeemed_,\n            feeCalcs_.qACFee,\n            feeCalcs_.qFeeToken,\n            feeCalcs_.qACVendorMarkup,\n            feeCalcs_.qFeeTokenVendorMarkup,\n            params_.vendor,\n            operId_\n        );\n    }\n\n    /**\n     * @notice hook after mintTP Operation is executed, emits the TPMinted event\n     * @param operId_ Identifier to track the Operation lifecycle\n     * @param params_ mintTP functions params\n     * @param qACtotalNeeded_ amount of AC needed to mint qTP\n     * @param feeCalcs_ platform fee detail breakdown\n     */\n    function _onDeferredTPMinted(\n        uint256 operId_,\n        MocCore.MintTPParams memory params_,\n        uint256 qACtotalNeeded_,\n        MocCore.FeeCalcs memory feeCalcs_\n    ) internal {\n        emit TPMinted(\n            params_.tp,\n            params_.sender,\n            params_.recipient,\n            params_.qTP,\n            qACtotalNeeded_,\n            feeCalcs_.qACFee,\n            feeCalcs_.qFeeToken,\n            feeCalcs_.qACVendorMarkup,\n            feeCalcs_.qFeeTokenVendorMarkup,\n            params_.vendor,\n            operId_\n        );\n    }\n\n    /**\n     * @notice Hook after the TP is redeemed, with operation information result\n     * @param operId_ operation id\n     * @param params_ redeemTPto function params\n     * @param qACRedeemed_ amount of AC redeemed\n     * @param feeCalcs_ platform fee detail breakdown\n     */\n    function _onDeferredTPRedeemed(\n        uint256 operId_,\n        MocCore.RedeemTPParams memory params_,\n        uint256 qACRedeemed_,\n        MocCore.FeeCalcs memory feeCalcs_\n    ) internal {\n        emit TPRedeemed(\n            params_.tp,\n            params_.sender,\n            params_.recipient,\n            params_.qTP,\n            qACRedeemed_,\n            feeCalcs_.qACFee,\n            feeCalcs_.qFeeToken,\n            feeCalcs_.qACVendorMarkup,\n            feeCalcs_.qFeeTokenVendorMarkup,\n            params_.vendor,\n            operId_\n        );\n    }\n\n    /**\n     * @notice Hook after the TC and TP are minted, with operation information result\n     * @param operId_ operation id\n     * @param params_ mintTCandTPto function params\n     * @param qTCMinted_ amount of qTC minted for the given qTP\n     * @param qACtoMintTC_ amount of AC used to mint TC\n     * @param qACtoMintTP_ amount of AC used to mint TP\n     * @param qACtoSpent_ total amount of AC spent by user\n     * @param feeCalcs_ platform fee detail breakdown\n     */\n    function _onDeferredTCandTPMinted(\n        uint256 operId_,\n        MocCore.MintTCandTPParams memory params_,\n        uint256 qTCMinted_,\n        uint256 qACtoMintTC_,\n        uint256 qACtoMintTP_,\n        uint256 qACtoSpent_,\n        MocCore.FeeCalcs memory feeCalcs_\n    ) internal {\n        emit TCandTPMinted(\n            params_.tp,\n            params_.sender,\n            params_.recipient,\n            qTCMinted_,\n            params_.qTP,\n            qACtoSpent_,\n            qACtoMintTC_,\n            qACtoMintTP_,\n            feeCalcs_.qACFee,\n            feeCalcs_.qFeeToken,\n            feeCalcs_.qACVendorMarkup,\n            feeCalcs_.qFeeTokenVendorMarkup,\n            params_.vendor,\n            operId_\n        );\n    }\n\n    /**\n     * @notice Hook after the TC and TP are redeemed, with operation information result\n     * @param operId_ operation id\n     * @param params_ redeemTCandTPto function params\n     * @param qTCRedeemed_ total amount of TC redeemed\n     * @param qACtoRedeemTC_ amount of AC redeemed due to TC redemption\n     * @param qACtoRedeemTP_ amount of AC redeemed due to TP redemption\n     * @param qACtoReceive_ total AC received by user after fees\n     * @param feeCalcs_ platform fee detail breakdown\n     */\n    function _onDeferredTCandTPRedeemed(\n        uint256 operId_,\n        MocCore.RedeemTCandTPParams memory params_,\n        uint256 qTCRedeemed_,\n        uint256 qACtoRedeemTC_,\n        uint256 qACtoRedeemTP_,\n        uint256 qACtoReceive_,\n        MocCore.FeeCalcs memory feeCalcs_\n    ) internal {\n        emit TCandTPRedeemed(\n            params_.tp,\n            params_.sender,\n            params_.recipient,\n            qTCRedeemed_,\n            params_.qTP,\n            qACtoReceive_,\n            qACtoRedeemTC_,\n            qACtoRedeemTP_,\n            feeCalcs_.qACFee,\n            feeCalcs_.qFeeToken,\n            feeCalcs_.qACVendorMarkup,\n            feeCalcs_.qFeeTokenVendorMarkup,\n            params_.vendor,\n            operId_\n        );\n    }\n\n    /**\n     * @notice Hook after the TC is swapped for TP, with operation information result\n     * @param operId_ operation id\n     * @param params_ swapTCforTP function params\n     * @param qTPMinted_ total amount of TP swapped\n     * @param feeCalcs_ platform fee detail breakdown\n     */\n    function _onDeferredTCforTPSwapped(\n        uint256 operId_,\n        MocCore.SwapTCforTPParams memory params_,\n        uint256 qTPMinted_,\n        MocCore.FeeCalcs memory feeCalcs_\n    ) internal {\n        emit TCSwappedForTP(\n            params_.tp,\n            params_.sender,\n            params_.recipient,\n            params_.qTC,\n            qTPMinted_,\n            feeCalcs_.qACFee,\n            feeCalcs_.qFeeToken,\n            feeCalcs_.qACVendorMarkup,\n            feeCalcs_.qFeeTokenVendorMarkup,\n            params_.vendor,\n            operId_\n        );\n    }\n\n    /**\n     * @notice Hook after the TP is swapped for TC, with operation information result\n     * @param operId_ operation id\n     * @param params_ swapTPforTC function params\n     * @param qTCMinted_ total amount of TC minted\n     * @param feeCalcs_ platform fee detail breakdown\n     */\n    function _onDeferredTPforTCSwapped(\n        uint256 operId_,\n        MocCore.SwapTPforTCParams memory params_,\n        uint256 qTCMinted_,\n        MocCore.FeeCalcs memory feeCalcs_\n    ) internal {\n        emit TPSwappedForTC(\n            params_.tp,\n            params_.sender,\n            params_.recipient,\n            params_.qTP,\n            qTCMinted_,\n            feeCalcs_.qACFee,\n            feeCalcs_.qFeeToken,\n            feeCalcs_.qACVendorMarkup,\n            feeCalcs_.qFeeTokenVendorMarkup,\n            params_.vendor,\n            operId_\n        );\n    }\n\n    /**\n     * @notice Hook after the TP is swapped for another TP, with operation information result\n     * @param operId_ operation id\n     * @param params_ swapTPforTP function params\n     * @param qTPMinted_ total amount of TP `iTo` minted\n     * @param feeCalcs_ platform fee detail breakdown\n     */\n    function _onDeferredTPforTPSwapped(\n        uint256 operId_,\n        MocCore.SwapTPforTPParams memory params_,\n        uint256 qTPMinted_,\n        MocCore.FeeCalcs memory feeCalcs_\n    ) internal {\n        emit TPSwappedForTP(\n            params_.tpFrom,\n            params_.tpTo,\n            params_.sender,\n            params_.recipient,\n            params_.qTP,\n            qTPMinted_,\n            feeCalcs_.qACFee,\n            feeCalcs_.qFeeToken,\n            feeCalcs_.qACVendorMarkup,\n            feeCalcs_.qFeeTokenVendorMarkup,\n            params_.vendor,\n            operId_\n        );\n    }\n\n    /**\n     * @notice unlocks AC in pending, handling any error\n     * @dev AC transfers may fail in rare edge cases, including:\n     *      1. For coinbase: if the sender is a contract without fallback function\n     *      2. For RC20: if the token is paused or the sender is blacklisted\n     *  To avoid blocking the execution of the queue, these errors are caught and handled.\n     *  In such cases, the funds remain locked in the bucket and can later be addressed\n     *  by governance depending on the specific situation.\n     * @param bucket_ bucket that is intended to operate\n     * @param operId_ operation id\n     * @param sender_ sender that is intended to unlock\n     * @param qAC_ amount of AC to unlock\n     */\n    function _unlockACInPending(MocOperations bucket_, uint256 operId_, address sender_, uint256 qAC_) internal {\n        try bucket_.unlockACInPending(sender_, qAC_) {} catch {\n            emit ACUnlockFailed(operId_, sender_, qAC_);\n            senderLockedFunds[sender_] += qAC_;\n            totalLockedFunds += qAC_;\n        }\n    }\n\n    /**\n     * @notice Executes mint TC handling any error\n     * @param bucket_ bucket that is intended to operate\n     * @param operId_ operation id\n     *\n     * May emit {TCMinted, OperationError, UnhandledError} events\n     */\n    function _executeMintTC(MocOperations bucket_, uint256 operId_) internal virtual {\n        MocCore.MintTCParams memory params = operationsMintTC[operId_];\n        try bucket_.execMintTC(params) returns (uint256 _qACtotalNeeded, MocCore.FeeCalcs memory _feeCalcs) {\n            _onDeferredTCMinted(operId_, params, _qACtotalNeeded, _feeCalcs);\n        } catch (bytes memory returnData) {\n            // padded/shifted as decode only takes bytes32 chunks and error selector is just 4 bytes.\n            bytes4 errorSelector = bytes4(returnData);\n            if (errorSelector == MocCommons.InsufficientQacSent.selector) {\n                emit OperationError(operId_, errorSelector, INSUFFICIENT_AC_SENT);\n            } else if (errorSelector == MocBaseBucket.LowCoverage.selector) {\n                emit OperationError(operId_, errorSelector, LOW_COVERAGE);\n            } else emit UnhandledError(operId_, returnData);\n\n            // On a failed Operation, we unlock user funds\n            _unlockACInPending(bucket_, operId_, params.sender, params.qACmax);\n        }\n    }\n\n    /**\n     * @notice Executes redeem TC handling any error\n     * @param bucket_ bucket that is intended to operate\n     * @param operId_ operation id\n     *\n     * May emit {TCRedeemed, OperationError, UnhandledError} events\n     */\n    function _executeRedeemTC(MocOperations bucket_, uint256 operId_) internal virtual {\n        MocCore.RedeemTCParams memory params = operationsRedeemTC[operId_];\n        try bucket_.execRedeemTC(params) returns (uint256 _qACRedeemed, MocCore.FeeCalcs memory _feeCalcs) {\n            _onDeferredTCRedeemed(operId_, params, _qACRedeemed, _feeCalcs);\n        } catch (bytes memory returnData) {\n            // padded/shifted as decode only takes bytes32 chunks and error selector is just 4 bytes.\n            bytes4 errorSelector = bytes4(returnData);\n            if (errorSelector == MocCommons.InsufficientTCtoRedeem.selector) {\n                emit OperationError(operId_, errorSelector, INSUFFICIENT_TC_TO_REDEEM);\n            } else if (errorSelector == MocCommons.QacBelowMinimumRequired.selector) {\n                emit OperationError(operId_, errorSelector, AC_BELOW_MINIMUM);\n            } else if (errorSelector == MocBaseBucket.LowCoverage.selector) {\n                emit OperationError(operId_, errorSelector, LOW_COVERAGE);\n            } else emit UnhandledError(operId_, returnData);\n\n            // On a failed Operation, we unlock user funds\n            bucket_.unlockTCInPending(params.sender, params.qTC);\n        }\n    }\n\n    /**\n     * @notice Executes mint TP handling any error\n     * @param bucket_ bucket that is intended to operate\n     * @param operId_ operation id\n     *\n     * May emit {TPMinted, OperationError, UnhandledError} events\n     */\n    function _executeMintTP(MocOperations bucket_, uint256 operId_) internal virtual {\n        MocCore.MintTPParams memory params = operationsMintTP[operId_];\n        try bucket_.execMintTP(params) returns (uint256 _qACtotalNeeded, MocCore.FeeCalcs memory _feeCalcs) {\n            _onDeferredTPMinted(operId_, params, _qACtotalNeeded, _feeCalcs);\n        } catch (bytes memory returnData) {\n            // padded/shifted as decode only takes bytes32 chunks and error selector is just 4 bytes.\n            bytes4 errorSelector = bytes4(returnData);\n            if (errorSelector == MocCommons.MaxFluxCapacitorOperationReached.selector) {\n                emit OperationError(operId_, errorSelector, FLUX_CAPACITOR);\n            } else if (errorSelector == MocCommons.InsufficientTPtoMint.selector) {\n                emit OperationError(operId_, errorSelector, INSUFFICIENT_TP_TO_MINT);\n            } else if (errorSelector == MocCommons.InsufficientQacSent.selector) {\n                emit OperationError(operId_, errorSelector, INSUFFICIENT_AC_SENT);\n            } else if (errorSelector == MocBaseBucket.LowCoverage.selector) {\n                emit OperationError(operId_, errorSelector, LOW_COVERAGE);\n            } else emit UnhandledError(operId_, returnData);\n\n            // On a failed Operation, we unlock user funds\n            _unlockACInPending(bucket_, operId_, params.sender, params.qACmax);\n        }\n    }\n\n    /**\n     * @notice Executes redeem TP handling any error\n     * @param bucket_ bucket that is intended to operate\n     * @param operId_ operation id\n     *\n     * May emit {TPRedeemed, OperationError, UnhandledError} events\n     */\n    function _executeRedeemTP(MocOperations bucket_, uint256 operId_) internal virtual {\n        MocCore.RedeemTPParams memory params = operationsRedeemTP[operId_];\n        try bucket_.execRedeemTP(params) returns (uint256 _qACRedeemed, MocCore.FeeCalcs memory _feeCalcs) {\n            _onDeferredTPRedeemed(operId_, params, _qACRedeemed, _feeCalcs);\n        } catch (bytes memory returnData) {\n            // padded/shifted as decode only takes bytes32 chunks and error selector is just 4 bytes.\n            bytes4 errorSelector = bytes4(returnData);\n            if (errorSelector == MocCommons.MaxFluxCapacitorOperationReached.selector) {\n                emit OperationError(operId_, errorSelector, FLUX_CAPACITOR);\n            } else if (errorSelector == MocCommons.QacBelowMinimumRequired.selector) {\n                emit OperationError(operId_, errorSelector, AC_BELOW_MINIMUM);\n            } else if (errorSelector == MocBaseBucket.LowCoverage.selector) {\n                emit OperationError(operId_, errorSelector, LOW_COVERAGE);\n            } else emit UnhandledError(operId_, returnData);\n\n            // On a failed Operation, we unlock user funds\n            bucket_.unlockTPInPending(params.sender, IERC20Upgradeable(params.tp), params.qTP);\n        }\n    }\n\n    /**\n     * @notice Executes mint TC and TP handling any error\n     * @param bucket_ bucket that is intended to operate\n     * @param operId_ operation id\n     *\n     * May emit {TCandTPMinted, OperationError, UnhandledError} events\n     */\n    function _executeMintTCandTP(MocOperations bucket_, uint256 operId_) internal virtual {\n        MocCore.MintTCandTPParams memory params = operationsMintTCandTP[operId_];\n        try bucket_.execMintTCandTP(params) returns (\n            uint256 _qACtoMintTC,\n            uint256 _qACtoMintTP,\n            uint256 _qACtoSpent,\n            uint256 _qTcMinted,\n            MocCore.FeeCalcs memory _feeCalcs\n        ) {\n            _onDeferredTCandTPMinted(operId_, params, _qTcMinted, _qACtoMintTC, _qACtoMintTP, _qACtoSpent, _feeCalcs);\n        } catch (bytes memory returnData) {\n            // padded/shifted as decode only takes bytes32 chunks and error selector is just 4 bytes.\n            bytes4 errorSelector = bytes4(returnData);\n            if (errorSelector == MocCommons.MaxFluxCapacitorOperationReached.selector) {\n                emit OperationError(operId_, errorSelector, FLUX_CAPACITOR);\n            } else if (errorSelector == MocCommons.InsufficientQacSent.selector) {\n                emit OperationError(operId_, errorSelector, INSUFFICIENT_AC_SENT);\n            } else if (errorSelector == MocBaseBucket.LowCoverage.selector) {\n                emit OperationError(operId_, errorSelector, LOW_COVERAGE);\n            } else emit UnhandledError(operId_, returnData);\n\n            // On a failed Operation, we unlock user funds\n            _unlockACInPending(bucket_, operId_, params.sender, params.qACmax);\n        }\n    }\n\n    /**\n     * @notice Executes redeem TC and TP handling any error\n     * @param bucket_ bucket that is intended to operate\n     * @param operId_ operation id\n     *\n     * May emit {TCandTPRedeemed, OperationError, UnhandledError} events\n     */\n    function _executeRedeemTCandTP(MocOperations bucket_, uint256 operId_) internal virtual {\n        MocCore.RedeemTCandTPParams memory params = operationsRedeemTCandTP[operId_];\n        try bucket_.execRedeemTCandTP(params) returns (\n            uint256 _qACtoRedeemTC,\n            uint256 _qACtoRedeemTP,\n            uint256 _qACtoReceive,\n            uint256 _qTCRedeemed,\n            MocCore.FeeCalcs memory _feeCalcs\n        ) {\n            _onDeferredTCandTPRedeemed(\n                operId_,\n                params,\n                _qTCRedeemed,\n                _qACtoRedeemTC,\n                _qACtoRedeemTP,\n                _qACtoReceive,\n                _feeCalcs\n            );\n        } catch (bytes memory returnData) {\n            // padded/shifted as decode only takes bytes32 chunks and error selector is just 4 bytes.\n            bytes4 errorSelector = bytes4(returnData);\n            if (errorSelector == MocCommons.MaxFluxCapacitorOperationReached.selector) {\n                emit OperationError(operId_, errorSelector, FLUX_CAPACITOR);\n            } else if (errorSelector == MocCommons.InsufficientQtcSent.selector) {\n                emit OperationError(operId_, errorSelector, INSUFFICIENT_TC_SENT);\n            } else if (errorSelector == MocCommons.QacBelowMinimumRequired.selector) {\n                emit OperationError(operId_, errorSelector, AC_BELOW_MINIMUM);\n            } else if (errorSelector == MocBaseBucket.LowCoverage.selector) {\n                emit OperationError(operId_, errorSelector, LOW_COVERAGE);\n            } else emit UnhandledError(operId_, returnData);\n\n            // On a failed Operation, we unlock user funds\n            bucket_.unlockTPInPending(params.sender, IERC20Upgradeable(params.tp), params.qTP);\n            bucket_.unlockTCInPending(params.sender, params.qTC);\n        }\n    }\n\n    /**\n     * @notice Executes swap TC for TP handling any error\n     * @param bucket_ bucket that is intended to operate\n     * @param operId_ operation id\n     *\n     * May emit {TCforTPSwapped, OperationError, UnhandledError} events\n     */\n    function _executeSwapTCforTP(MocOperations bucket_, uint256 operId_) internal virtual {\n        MocCore.SwapTCforTPParams memory params = operationsSwapTCforTP[operId_];\n        try bucket_.execSwapTCforTP(params) returns (uint256 qTPMinted, MocCore.FeeCalcs memory feeCalcs) {\n            _onDeferredTCforTPSwapped(operId_, params, qTPMinted, feeCalcs);\n        } catch (bytes memory returnData) {\n            // padded/shifted as decode only takes bytes32 chunks and error selector is just 4 bytes.\n            bytes4 errorSelector = bytes4(returnData);\n            if (errorSelector == MocCommons.MaxFluxCapacitorOperationReached.selector) {\n                emit OperationError(operId_, errorSelector, FLUX_CAPACITOR);\n            } else if (errorSelector == MocCommons.InsufficientTCtoRedeem.selector) {\n                emit OperationError(operId_, errorSelector, INSUFFICIENT_TC_TO_REDEEM);\n            } else if (errorSelector == MocCommons.InsufficientTPtoMint.selector) {\n                emit OperationError(operId_, errorSelector, INSUFFICIENT_TP_TO_MINT);\n            } else if (errorSelector == MocCommons.InsufficientQacSent.selector) {\n                emit OperationError(operId_, errorSelector, INSUFFICIENT_AC_SENT);\n            } else if (errorSelector == MocCommons.QtpBelowMinimumRequired.selector) {\n                emit OperationError(operId_, errorSelector, TP_BELOW_MINIMUM);\n            } else if (errorSelector == MocBaseBucket.LowCoverage.selector) {\n                emit OperationError(operId_, errorSelector, LOW_COVERAGE);\n            } else emit UnhandledError(operId_, returnData);\n\n            // On a failed Operation, we unlock user funds\n            bucket_.unlockTCInPending(params.sender, params.qTC);\n            _unlockACInPending(bucket_, operId_, params.sender, params.qACmax);\n        }\n    }\n\n    /**\n     * @notice Executes swap TP for TC handling any error\n     * @param bucket_ bucket that is intended to operate\n     * @param operId_ operation id\n     *\n     * May emit {TPforTCSwapped, OperationError, UnhandledError} events\n     */\n    function _executeSwapTPforTC(MocOperations bucket_, uint256 operId_) internal virtual {\n        MocCore.SwapTPforTCParams memory params = operationsSwapTPforTC[operId_];\n        try bucket_.execSwapTPforTC(params) returns (uint256 qTCMinted, MocCore.FeeCalcs memory feeCalcs) {\n            _onDeferredTPforTCSwapped(operId_, params, qTCMinted, feeCalcs);\n        } catch (bytes memory returnData) {\n            // padded/shifted as decode only takes bytes32 chunks and error selector is just 4 bytes.\n            bytes4 errorSelector = bytes4(returnData);\n            if (errorSelector == MocCommons.MaxFluxCapacitorOperationReached.selector) {\n                emit OperationError(operId_, errorSelector, FLUX_CAPACITOR);\n            } else if (errorSelector == MocCommons.InsufficientQacSent.selector) {\n                emit OperationError(operId_, errorSelector, INSUFFICIENT_AC_SENT);\n            } else if (errorSelector == MocCommons.QtcBelowMinimumRequired.selector) {\n                emit OperationError(operId_, errorSelector, TC_BELOW_MINIMUM);\n            } else if (errorSelector == MocBaseBucket.LowCoverage.selector) {\n                emit OperationError(operId_, errorSelector, LOW_COVERAGE);\n            } else emit UnhandledError(operId_, returnData);\n\n            // On a failed Operation, we unlock user funds\n            bucket_.unlockTPInPending(params.sender, IERC20Upgradeable(params.tp), params.qTP);\n            _unlockACInPending(bucket_, operId_, params.sender, params.qACmax);\n        }\n    }\n\n    /**\n     * @notice Executes swap TP for TP handling any error\n     * @param bucket_ bucket that is intended to operate\n     * @param operId_ operation id\n     *\n     * May emit {TPforTPSwapped, OperationError, UnhandledError} events\n     */\n    function _executeSwapTPforTP(MocOperations bucket_, uint256 operId_) internal virtual {\n        MocCore.SwapTPforTPParams memory params = operationsSwapTPforTP[operId_];\n        try bucket_.execSwapTPforTP(params) returns (uint256 qTPMinted, MocCore.FeeCalcs memory feeCalcs) {\n            _onDeferredTPforTPSwapped(operId_, params, qTPMinted, feeCalcs);\n        } catch (bytes memory returnData) {\n            // padded/shifted as decode only takes bytes32 chunks and error selector is just 4 bytes.\n            bytes4 errorSelector = bytes4(returnData);\n            if (errorSelector == MocCommons.InsufficientTPtoMint.selector) {\n                emit OperationError(operId_, errorSelector, INSUFFICIENT_TP_TO_MINT);\n            } else if (errorSelector == MocCommons.InsufficientQacSent.selector) {\n                emit OperationError(operId_, errorSelector, INSUFFICIENT_AC_SENT);\n            } else if (errorSelector == MocCommons.QtpBelowMinimumRequired.selector) {\n                emit OperationError(operId_, errorSelector, TP_BELOW_MINIMUM);\n            } else if (errorSelector == MocBaseBucket.LowCoverage.selector) {\n                emit OperationError(operId_, errorSelector, LOW_COVERAGE);\n            } else emit UnhandledError(operId_, returnData);\n\n            // On a failed Operation, we unlock user funds\n            bucket_.unlockTPInPending(params.sender, IERC20Upgradeable(params.tpFrom), params.qTP);\n            _unlockACInPending(bucket_, operId_, params.sender, params.qACmax);\n        }\n    }\n\n    /**\n     * @notice executes the given Operation by the `operId_`\n     * @dev does not revert on Operation failure, throws Process and Error\n     * events according to the Oper type and result\n     * @param operId_ Id of the Operation to be executed\n     * @param operType_ type of the Operation to be executed\n     * @param bucket_ bucket that is intended to operate\n     */\n    //solhint-disable-next-line code-complexity\n    function _executeOper(uint256 operId_, OperType operType_, MocOperations bucket_) internal {\n        if (operType_ == OperType.mintTC) {\n            _executeMintTC(bucket_, operId_);\n            delete operationsMintTC[operId_];\n        } else if (operType_ == OperType.redeemTC) {\n            _executeRedeemTC(bucket_, operId_);\n            delete operationsRedeemTC[operId_];\n        } else if (operType_ == OperType.mintTP) {\n            _executeMintTP(bucket_, operId_);\n            delete operationsMintTP[operId_];\n        } else if (operType_ == OperType.redeemTP) {\n            _executeRedeemTP(bucket_, operId_);\n            delete operationsRedeemTP[operId_];\n        } else if (operType_ == OperType.mintTCandTP) {\n            _executeMintTCandTP(bucket_, operId_);\n            delete operationsMintTCandTP[operId_];\n        } else if (operType_ == OperType.redeemTCandTP) {\n            _executeRedeemTCandTP(bucket_, operId_);\n            delete operationsRedeemTCandTP[operId_];\n        } else if (operType_ == OperType.swapTCforTP) {\n            _executeSwapTCforTP(bucket_, operId_);\n            delete operationsSwapTCforTP[operId_];\n        } else if (operType_ == OperType.swapTPforTC) {\n            _executeSwapTPforTC(bucket_, operId_);\n            delete operationsSwapTPforTC[operId_];\n        } else if (operType_ == OperType.swapTPforTP) {\n            _executeSwapTPforTP(bucket_, operId_);\n            delete operationsSwapTPforTP[operId_];\n        }\n    }\n\n    /**\n     * @notice gets the last block in which the queued operations can be executed.\n     *  Only operations enqueued before `blocksSinceLastPublication_` can be executed,\n     *  but they must have been queued for at least `minOperWaitingBlk_` and at most `maxOperWaitingBlk_`\n     * @param blocksSinceLastPublication_ amount of blocks since last price publication\n     * @param minOperWaitingBlk_ min amount of blocks the operation should wait in the Queue before execution\n     * @param maxOperWaitingBlk_ max amount of blocks the operation should wait in the Queue before execution\n     * @return lastBlockToExecute last block to execute operations\n     */\n    function _getLastBlockToExecute(\n        uint256 blocksSinceLastPublication_,\n        uint256 minOperWaitingBlk_,\n        uint256 maxOperWaitingBlk_\n    ) internal view returns (uint256 lastBlockToExecute) {\n        uint256 qBlocksToExecute;\n        if (blocksSinceLastPublication_ >= maxOperWaitingBlk_) {\n            qBlocksToExecute = maxOperWaitingBlk_;\n        } else {\n            // when maxOperWaitingBlk_ < blocksSinceLastPublication_, this max is not necessary to calculate\n            // because maxOperWaitingBlk_ is always > minOperWaitingBlk_ by parameter\n            qBlocksToExecute = Math.max(minOperWaitingBlk_, blocksSinceLastPublication_);\n        }\n        return block.number - qBlocksToExecute;\n    }\n\n    // ------- External Functions -------\n\n    /**\n     * @notice executes operation on a batch, controlled by MocMultiCollateralGuard contract\n     * @dev does not revert on Operation failure, throws Process and Error\n     * events according to the Oper type and result\n     * @param executor_ executor address\n     * @param maxOperPerBatch_ max amount of operations allowed to be executed\n     * @param blocksSinceLastPublication_ amount of blocks since last price publication\n     * @return totalExecutionFee total amount of execution fee to be sent to the execution fee recipient\n     * @return totalPriceUpdateFee total amount of price update fee to be sent to the price update fee recipient\n     * @return totalOperExecuted total amount of operations executed\n     */\n    function execute(\n        address executor_,\n        uint256 maxOperPerBatch_,\n        uint256 blocksSinceLastPublication_\n    )\n        external\n        onlyMocMultiCollateralGuard\n        returns (uint256 totalExecutionFee, uint256 totalPriceUpdateFee, uint256 totalOperExecuted)\n    {\n        uint256 operId = firstOperId;\n        uint256 lastOperId;\n        uint256 limitBlk;\n        uint256 localPriceUpdatesCost = priceUpdatesCost;\n        unchecked {\n            lastOperId = Math.min(operIdCount, operId + maxOperPerBatch_);\n            limitBlk = _getLastBlockToExecute(blocksSinceLastPublication_, minOperWaitingBlk, maxOperWaitingBlk);\n        }\n        MocOperations bucket = mocOperations;\n        // loop through all pending Operations\n        while (operId < lastOperId) {\n            OperInfo memory operInfo = opersInfo[operId];\n            // If current Operation has not met the waiting block criteria, we end the loop\n            if (operInfo.queuedBlk > limitBlk) break;\n\n            _executeOper(operId, operInfo.operType, bucket);\n            emit OperationExecuted(executor_, operId);\n            delete opersInfo[operId];\n            unchecked {\n                operId = operId + 1;\n                totalExecutionFee += execCost[operInfo.operType];\n                totalPriceUpdateFee += localPriceUpdatesCost;\n            }\n        }\n        unchecked {\n            uint256 baseFee = _getBaseFee();\n            totalOperExecuted = operId - firstOperId;\n            totalExecutionFee = totalExecutionFee * baseFee;\n            totalPriceUpdateFee = totalPriceUpdateFee * baseFee;\n        }\n        // Define new reference to queue beginning\n        firstOperId = operId;\n    }\n\n    /**\n     * @notice registered enqueuer can queue an Operations\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function queueMintTC(\n        MocCore.MintTCParams calldata params\n    ) external notPaused onlyMocBucket returns (uint256 operId) {\n        operId = operIdCount;\n        opersInfo[operId] = OperInfo(OperType.mintTC, uint248(block.number));\n        operationsMintTC[operId] = params;\n        emit OperationQueued(msg.sender, operId, OperType.mintTC);\n        operIdCount = unchecked_inc(operIdCount);\n    }\n\n    /**\n     * @notice registered enqueuer can queue an Operations\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function queueRedeemTC(\n        MocCore.RedeemTCParams calldata params\n    ) external notPaused onlyMocBucket returns (uint256 operId) {\n        operId = operIdCount;\n        opersInfo[operId] = OperInfo(OperType.redeemTC, uint248(block.number));\n        operationsRedeemTC[operId] = params;\n        emit OperationQueued(msg.sender, operId, OperType.redeemTC);\n        operIdCount = unchecked_inc(operIdCount);\n    }\n\n    /**\n     * @notice registered enqueuer can queue an Operations\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function queueMintTP(\n        MocCore.MintTPParams calldata params\n    ) external notPaused onlyMocBucket returns (uint256 operId) {\n        operId = operIdCount;\n        opersInfo[operId] = OperInfo(OperType.mintTP, uint248(block.number));\n        operationsMintTP[operId] = params;\n        emit OperationQueued(msg.sender, operId, OperType.mintTP);\n        operIdCount = unchecked_inc(operIdCount);\n    }\n\n    /**\n     * @notice Registered enqueuer can queue an Operations\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function queueRedeemTP(\n        MocCore.RedeemTPParams calldata params\n    ) external notPaused onlyMocBucket returns (uint256 operId) {\n        operId = operIdCount;\n        opersInfo[operId] = OperInfo(OperType.redeemTP, uint248(block.number));\n        operationsRedeemTP[operId] = params;\n        emit OperationQueued(msg.sender, operId, OperType.redeemTP);\n        operIdCount = unchecked_inc(operIdCount);\n    }\n\n    /**\n     * @notice Registered enqueuer can queue an Operations\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function queueMintTCandTP(\n        MocCore.MintTCandTPParams calldata params\n    ) external notPaused onlyMocBucket returns (uint256 operId) {\n        operId = operIdCount;\n        opersInfo[operId] = OperInfo(OperType.mintTCandTP, uint248(block.number));\n        operationsMintTCandTP[operId] = params;\n        emit OperationQueued(msg.sender, operId, OperType.mintTCandTP);\n        operIdCount = unchecked_inc(operIdCount);\n    }\n\n    /**\n     * @notice Registered enqueuer can queue an Operations\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function queueRedeemTCandTP(\n        MocCore.RedeemTCandTPParams calldata params\n    ) external notPaused onlyMocBucket returns (uint256 operId) {\n        operId = operIdCount;\n        opersInfo[operId] = OperInfo(OperType.redeemTCandTP, uint248(block.number));\n        operationsRedeemTCandTP[operId] = params;\n        emit OperationQueued(msg.sender, operId, OperType.redeemTCandTP);\n        operIdCount = unchecked_inc(operIdCount);\n    }\n\n    /**\n     * @notice Registered enqueuer can queue an Operations\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function queueSwapTCforTP(\n        MocCore.SwapTCforTPParams calldata params\n    ) external notPaused onlyMocBucket returns (uint256 operId) {\n        operId = operIdCount;\n        opersInfo[operId] = OperInfo(OperType.swapTCforTP, uint248(block.number));\n        operationsSwapTCforTP[operId] = params;\n        emit OperationQueued(msg.sender, operId, OperType.swapTCforTP);\n        operIdCount = unchecked_inc(operIdCount);\n    }\n\n    /**\n     * @notice Registered enqueuer can queue an Operations\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function queueSwapTPforTC(\n        MocCore.SwapTPforTCParams calldata params\n    ) external notPaused onlyMocBucket returns (uint256 operId) {\n        operId = operIdCount;\n        opersInfo[operId] = OperInfo(OperType.swapTPforTC, uint248(block.number));\n        operationsSwapTPforTC[operId] = params;\n        emit OperationQueued(msg.sender, operId, OperType.swapTPforTC);\n        operIdCount = unchecked_inc(operIdCount);\n    }\n\n    /**\n     * @notice Registered enqueuer can queue an Operations\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function queueSwapTPforTP(\n        MocCore.SwapTPforTPParams calldata params\n    ) external notPaused onlyMocBucket returns (uint256 operId) {\n        operId = operIdCount;\n        opersInfo[operId] = OperInfo(OperType.swapTPforTP, uint248(block.number));\n        operationsSwapTPforTP[operId] = params;\n        emit OperationQueued(msg.sender, operId, OperType.swapTPforTP);\n        operIdCount = unchecked_inc(operIdCount);\n    }\n\n    /**\n     * @notice true if the queue is empty\n     */\n    function isEmpty() public view override returns (bool) {\n        return firstOperId == operIdCount;\n    }\n\n    /**\n     * @notice true if the queue has at least one Operation ready to be executed\n     * @param blocksSinceLastPublication_ amount of blocks since last price publication\n     */\n    function readyToExecute(uint256 blocksSinceLastPublication_) external view returns (bool) {\n        if (isEmpty()) return false;\n        OperInfo memory operInfo = opersInfo[firstOperId];\n        return (operInfo.queuedBlk <=\n            _getLastBlockToExecute(blocksSinceLastPublication_, minOperWaitingBlk, maxOperWaitingBlk));\n    }\n\n    // ------- Only Authorized Changer Functions -------\n\n    /**\n     * @notice sets Moc Queue minimum operation waiting blocks\n     * @param minOperWaitingBlk_ minimum amount of blocks an operation needs to remain in the\n     * queue before it can be executed\n     */\n    function setMinOperWaitingBlk(uint256 minOperWaitingBlk_) external onlyAuthorizedChanger {\n        if (minOperWaitingBlk_ > maxOperWaitingBlk) revert InvalidValue();\n        minOperWaitingBlk = minOperWaitingBlk_;\n    }\n\n    /**\n     * @notice sets Moc Queue maximum operation waiting blocks\n     * @param maxOperWaitingBlk_ max amount of blocks the Operation should wait in the Queue.\n     * Even if there is no price update it can be executed after this amount of blocks\n     */\n    function setMaxOperWaitingBlk(uint256 maxOperWaitingBlk_) external onlyAuthorizedChanger {\n        if (minOperWaitingBlk > maxOperWaitingBlk_) revert InvalidValue();\n        maxOperWaitingBlk = maxOperWaitingBlk_;\n    }\n\n    /**\n     * @notice sets MocMultiCollateralGuard contract address\n     * @param mocMultiCollateralGuardAddress_ new MocMultiCollateralGuard contract address\n     */\n    function setMocMultiCollateralGuard(\n        MocMultiCollateralGuard mocMultiCollateralGuardAddress_\n    ) external onlyAuthorizedChanger {\n        mocMultiCollateralGuard = mocMultiCollateralGuardAddress_;\n    }\n\n    /**\n     * @notice registers the mocOperations bucket that would operate over this queue\n     * @param bucket_ address of the mocOperations implementation to interact with\n     */\n    function registerBucket(MocOperations bucket_) external onlyAuthorizedChanger {\n        if (address(mocOperations) != address(0)) revert BucketAlreadyRegistered();\n        mocOperations = bucket_;\n    }\n\n    /**\n     * @notice allows OperIdCount and firstOperId initialization\n     * @dev useful while migrating from and existing Operation Id count, initialize this\n     * values to avoid IDs duplications. Make sure the queue is paused so no operations\n     * can \"front run\" this assignment.\n     * @param operIdCount_ value to be assign to OperIdCount\n     * @param firstOperId_ value to be assign to firstOperId\n     */\n    function initOperId(uint256 operIdCount_, uint256 firstOperId_) external onlyAuthorizedChanger {\n        operIdCount = operIdCount_;\n        firstOperId = firstOperId_;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/core/MocEma.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocBaseBucket } from \"./MocBaseBucket.sol\";\n\n/**\n * @title MocEma: Exponential Moving Average\n * @notice Moc Ema, provides a set of methods that allows to calculate and track\n * Exponential Moving Average for each of the pegged Tokens.\n * @dev More information of EMA calculation https://en.wikipedia.org/wiki/Exponential_smoothing\n */\nabstract contract MocEma is MocBaseBucket {\n    // ------- Events -------\n    event TPemaUpdated(uint256 indexed i_, uint256 oldTPema_, uint256 newTPema_);\n\n    // ------- Structs -------\n    struct EmaItem {\n        // exponential moving average\n        uint256 ema;\n        // smoothing factor\n        uint256 sf;\n    }\n\n    // ------- Storage -------\n    // TP EMA items, indexes are in sync with PeggedTokens across Moc solution\n    EmaItem[] public tpEma;\n    // next ema calculation time\n    uint256 public nextEmaCalculation;\n    // amount of seconds to wait for next ema calculation\n    uint256 public emaCalculationTimeSpan;\n\n    /**\n     * @notice calculates exponential moving average of the value of a Pegged Token\n     * @dev more information of EMA calculation https://en.wikipedia.org/wiki/Exponential_smoothing\n     * @param currentTPema_ current Ema value\n     * @param pACtp_ current tp AC price\n     */\n    function _calcNewEma(EmaItem memory currentTPema_, uint256 pACtp_) private pure returns (uint256) {\n        // [PREC²] = [PREC] * ([PREC] - [PREC])\n        uint256 term1 = currentTPema_.ema * (ONE - currentTPema_.sf);\n        // [PREC²] = [PREC] * [PREC]\n        uint256 term2 = currentTPema_.sf * pACtp_;\n        // [PREC] = ([PREC²] + [PREC²]) / [PREC]\n        return (term1 + term2) / PRECISION;\n    }\n\n    // ------- Initializer -------\n    /**\n     * @notice contract initializer\n     * @param emaCalculationTimeSpan_ amount of seconds to wait between Pegged ema calculation\n     */\n    function __MocEma_init_unchained(uint256 emaCalculationTimeSpan_) internal onlyInitializing {\n        emaCalculationTimeSpan = emaCalculationTimeSpan_;\n        _updateNextEmaCalculation(emaCalculationTimeSpan_);\n    }\n\n    // ------- Internal Functions -------\n\n    /**\n     * @notice updates next EMA calculation\n     * @param emaCalculationTimeSpan_ amount of seconds to wait between Pegged ema calculation\n     */\n    function _updateNextEmaCalculation(uint256 emaCalculationTimeSpan_) internal {\n        unchecked {\n            nextEmaCalculation = block.timestamp + emaCalculationTimeSpan_;\n        }\n    }\n\n    /**\n     * @notice get target coverage adjusted by the moving average of the value of a Pegged Token\n     * @param i_ Pegged Token index\n     * @param pACtp_ Pegged Token price [PREC]\n     * @return ctargemaTP [PREC]\n     */\n    function _getCtargemaTP(uint256 i_, uint256 pACtp_, uint256 protThrld_) internal view returns (uint256 ctargemaTP) {\n        uint256 auxTpEma = tpEma[i_].ema;\n        if (shouldCalculateEma()) auxTpEma = _calcNewEma(tpEma[i_], pACtp_);\n        // [PREC] = ((([PREC] - [PREC]) * [PREC]) / [PREC]) + [PREC]\n        uint256 computedCtargemaTP = (((tpCtarg[i_] - ONE) * pACtp_) / auxTpEma) + ONE;\n        return computedCtargemaTP > protThrld_ ? computedCtargemaTP : protThrld_;\n    }\n\n    /**\n     * @notice update exponential moving average of the value of a Pegged Token\n     * @param i_ Pegged Token index\n     * @param pACtp_ tp price [PREC]\n     */\n    function _updateTPema(uint256 i_, uint256 pACtp_) internal {\n        EmaItem memory currentTPema = tpEma[i_];\n        uint256 newEma = _calcNewEma(currentTPema, pACtp_);\n        // save new ema value to storage\n        tpEma[i_].ema = newEma;\n        emit TPemaUpdated(i_, currentTPema.ema, newEma);\n    }\n\n    /**\n     * @notice calculates CA target coverage, adjusted by all Pegged Token's to\n     *  Collateral Asset last stored moving average price\n     * @dev WARN: if EMA are not up to date, the resulting coverage might not reflect real spot value\n     *      qAC = (nTP + tpGain) / pACtp\n     *      ctargemaCA = ∑(ctargemaTP * qAC) / ∑(qAC)\n     * @param pACtps_ All tps prices [PREC]\n     * @return ctargemaCA [PREC]\n     */\n    function _calcCtargemaCA(uint256[] memory pACtps_) internal view returns (uint256 ctargemaCA) {\n        uint256 num;\n        uint256 den;\n        uint256 localProtThrld = protThrld;\n        uint256 pegAmount = pegContainer.length;\n        for (uint256 i = 0; i < pegAmount; i = unchecked_inc(i)) {\n            uint256 pACtp = pACtps_[i];\n            (uint256 tpGain, ) = _getPnLTP(i, pACtp);\n            // [PREC] = [N] * [PREC] * [PREC]  / [PREC]\n            uint256 qAC = _divPrec((pegContainer[i].nTP + tpGain) * PRECISION, pACtp);\n            // [PREC]^2 = [PREC] * [PREC]\n            num += _getCtargemaTP(i, pACtp, localProtThrld) * qAC;\n            // [PREC] = [PREC]\n            den += qAC;\n        }\n        // we must return a default value when all nTP are 0\n        // slither-disable-next-line incorrect-equality\n        if (den == 0) {\n            unchecked {\n                return (localProtThrld * 2);\n            }\n        }\n        // [PREC] = ([PREC]^2) / [PREC]\n        ctargemaCA = num / den;\n    }\n\n    // ------- Public Functions -------\n\n    /**\n     * @notice calculates target coverage adjusted by all Pegged Token's to Collateral Asset rate moving average\n     * @dev qAC = nTP / pACtp\n     *      ctargemaCA = ∑(ctargemaTP * qAC) / ∑(qAC)\n     * @return ctargemaCA [PREC]\n     */\n    function getCtargemaCA() external view returns (uint256 ctargemaCA) {\n        return _calcCtargemaCA(_getPACtps());\n    }\n\n    /**\n     * @notice calculates target coverage adjusted by all Pegged Token's to Collateral Asset rate moving average\n     * @dev qAC = nTP / pACtp\n     *      ctargemaCA = ∑(ctargemaTP * qAC) / ∑(qAC)\n     * @param pACtps_ All tps prices [PREC]\n     * @return ctargemaCA [PREC]\n     */\n    function calcCtargemaCA(uint256[] memory pACtps_) external view returns (uint256 ctargemaCA) {\n        return _calcCtargemaCA(pACtps_);\n    }\n\n    /**\n     * @notice calculates target coverage adjusted by the moving average of the value of a Pegged Token\n     * @param tp_ Pegged Token address\n     * @return ctargemaTP [PREC]\n     */\n    function getCtargemaTP(address tp_) external view returns (uint256 ctargemaTP) {\n        uint256 i = _tpi(tp_);\n        return _getCtargemaTP(i, _getPACtp(i), protThrld);\n    }\n\n    /**\n     * @notice calculates target coverage adjusted by the moving average of the value of a Pegged Token\n     * @param tp_ Pegged Token address\n     * @param pACtp_ tp price [PREC]\n     * @return ctargemaTP [PREC]\n     */\n    function calcCtargemaTP(address tp_, uint256 pACtp_) external view returns (uint256 ctargemaTP) {\n        return _getCtargemaTP(_tpi(tp_), pACtp_, protThrld);\n    }\n\n    /**\n     * @notice true if the necessary span has pass since last ema update\n     */\n    function shouldCalculateEma() public view returns (bool) {\n        unchecked {\n            return block.timestamp >= nextEmaCalculation;\n        }\n    }\n\n    /**\n     * @notice If time, calculates the EMA for all the Pegged Token prices.\n     * @dev All price provider prices must be available, fails if not\n     */\n    function updateEmas() external {\n        if (shouldCalculateEma()) {\n            uint256[] memory pACtps = _getPACtps();\n            for (uint256 i = 0; i < pACtps.length; i = unchecked_inc(i)) {\n                _updateTPema(i, pACtps[i]);\n            }\n            _updateNextEmaCalculation(emaCalculationTimeSpan);\n        }\n    }\n\n    /**\n     * @param timeSpan_ Defines how many seconds should pass between EMA calculations\n     * @dev nextEmaCalculation is not automatically updated, you have to wait until next\n     *  EMA calculation to be made : nextEmaCalculation = block.timestamp + emaCalculationTimeSpan\n     **/\n    function setEmaCalculationTimeSpan(uint256 timeSpan_) external onlyAuthorizedChanger {\n        emaCalculationTimeSpan = timeSpan_;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/mocks/PriceProviderMock.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IPriceProvider } from \"../interfaces/IPriceProvider.sol\";\n\ncontract PriceProviderMock is IPriceProvider {\n    bytes32 public mocPrice;\n    bool public has;\n    bool public useLastPublicationBlock = false;\n    uint256 public lastPublicationBlock = 0;\n\n    /**\n     * @notice constructor\n     * @param price_ MoC price for mock contract\n     */\n    constructor(uint256 price_) {\n        mocPrice = bytes32(price_);\n        has = true;\n    }\n\n    function peek() external view returns (bytes32, bool) {\n        return (mocPrice, has);\n    }\n\n    function poke(uint256 price_) external {\n        mocPrice = bytes32(price_);\n        lastPublicationBlock = block.number;\n    }\n\n    function deprecatePriceProvider() external {\n        has = false;\n    }\n\n    function restorePriceProvider() external {\n        has = true;\n    }\n\n    function getLastPublicationBlock() external view returns (uint256) {\n        if (useLastPublicationBlock) return lastPublicationBlock;\n        else return block.number;\n    }\n\n    function setLastPublicationBlock(uint256 lastPublicationBlock_) external returns (uint256) {\n        useLastPublicationBlock = true;\n        lastPublicationBlock = lastPublicationBlock_;\n    }\n\n    function removeLastPublicationBlock() external {\n        useLastPublicationBlock = false;\n    }\n}\n"},{"file_path":"npm/price-oracle-interfaces@0.1.0/contracts/PriceProviderDummy.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.24;\n\nimport \"./interfaces/IPriceProvider.sol\";\n\n/// @title Dummy Price Provider (always fresh)\n/// @notice Returns a fixed price and reports the current block as last publication.\ncontract PriceProviderDummy is IPriceProvider {\n  uint256 public price;\n\n  constructor(uint256 _price) {\n    price = _price;\n  }\n\n  /// @dev Always returns the same price and `true`.\n  function peek() external view override returns (bytes32, bool) {\n    return (bytes32(price), true);\n  }\n\n  /// @dev Reports the *current* block to look fresh to age checkers.\n  function getLastPublicationBlock() external view override returns (uint256) {\n    return block.number;\n  }\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/interfaces/IMocMultiCollateralGuard.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\ninterface IMocMultiCollateralGuard {\n    /**\n     * @notice get combined coverage and combined ctargemaCA\n     * @param bucket_ bucket that is intended to operate\n     * @return combinedCglb combined coverage [PREC]\n     * @return combinedCtargemaCA combined ctargemaCA [PREC]\n     * @return bucketPACtps all tps prices for the given bucket [PREC]\n     */\n    function getCombinedValues(\n        address bucket_\n    ) external returns (uint256 combinedCglb, uint256 combinedCtargemaCA, uint256[] memory bucketPACtps);\n\n    /**\n     * @notice get combined values and TC available to redeem\n     * @param bucket_ bucket that is intended to operate\n     * @return realTCAvailableToRedeem real TC available to redeem [N]\n     * @return bucketPACtps all tps prices for the given bucket [PREC]\n     */\n    function getCombinedAndTC(\n        address bucket_\n    ) external returns (uint256 realTCAvailableToRedeem, uint256[] memory bucketPACtps);\n\n    /**\n     * @notice get combined values and TP available to mint\n     * @param bucket_ bucket that is intended to operate\n     * @param tp_ Pegged Token that is intended to operate\n     * @return realTPAvailableToMint real TP available to mint [N]\n     * @return bucketPACtps all tps prices for the given bucket [PREC]\n     */\n    function getCombinedAndTP(\n        address bucket_,\n        address tp_\n    ) external returns (uint256 realTPAvailableToMint, uint256[] memory bucketPACtps);\n\n    /**\n     * @notice get combined values, TC available to redeem and TP available to mint\n     * @param bucket_ bucket that is intended to operate\n     * @param tp_ Pegged Token that is intended to operate\n     * @return realTCAvailableToRedeem real TC available to redeem [N]\n     * @return realTPAvailableToMint real TP available to mint [N]\n     * @return bucketPACtps all tps prices for the given bucket [PREC]\n     */\n    function getCombinedAndTCAndTP(\n        address bucket_,\n        address tp_\n    ) external returns (uint256 realTCAvailableToRedeem, uint256 realTPAvailableToMint, uint256[] memory bucketPACtps);\n\n    /**\n     * @notice get total amount of buckets\n     * @return total amount of buckets\n     */\n    function getBucketAmount() external view returns (uint256);\n}\n"},{"file_path":"project/contracts/token/USDRIF/StableTokenV2.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport \"./MocRC20.sol\";\n// Import to allow compilation and deploy of ERC1967Proxy\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\ncontract StableTokenV2 is MocRC20 {\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n}\n"},{"file_path":"npm/@uniswap/swap-router-contracts@1.3.1/contracts/interfaces/IV3SwapRouter.sol","source_code":"// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.7.5;\npragma abicoder v2;\n\nimport '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol';\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface IV3SwapRouter is IUniswapV3SwapCallback {\n    struct ExactInputSingleParams {\n        address tokenIn;\n        address tokenOut;\n        uint24 fee;\n        address recipient;\n        uint256 amountIn;\n        uint256 amountOutMinimum;\n        uint160 sqrtPriceLimitX96;\n    }\n\n    /// @notice Swaps `amountIn` of one token for as much as possible of another token\n    /// @dev Setting `amountIn` to 0 will cause the contract to look up its own balance,\n    /// and swap the entire amount, enabling contracts to send tokens before calling this function.\n    /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata\n    /// @return amountOut The amount of the received token\n    function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);\n\n    struct ExactInputParams {\n        bytes path;\n        address recipient;\n        uint256 amountIn;\n        uint256 amountOutMinimum;\n    }\n\n    /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n    /// @dev Setting `amountIn` to 0 will cause the contract to look up its own balance,\n    /// and swap the entire amount, enabling contracts to send tokens before calling this function.\n    /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n    /// @return amountOut The amount of the received token\n    function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n\n    struct ExactOutputSingleParams {\n        address tokenIn;\n        address tokenOut;\n        uint24 fee;\n        address recipient;\n        uint256 amountOut;\n        uint256 amountInMaximum;\n        uint160 sqrtPriceLimitX96;\n    }\n\n    /// @notice Swaps as little as possible of one token for `amountOut` of another token\n    /// that may remain in the router after the swap.\n    /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata\n    /// @return amountIn The amount of the input token\n    function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);\n\n    struct ExactOutputParams {\n        bytes path;\n        address recipient;\n        uint256 amountOut;\n        uint256 amountInMaximum;\n    }\n\n    /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)\n    /// that may remain in the router after the swap.\n    /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata\n    /// @return amountIn The amount of the input token\n    function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/v1/TaskEvalLiquidationV1.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../ITask.sol\";\n\n/**\n * @title TaskEvalLiquidationV1\n * @notice This contract implements a task that evaluates if liquidation is needed and runs it if so.\n */\ncontract TaskEvalLiquidationV1 is ITask {\n    IMocV1 public immutable mocV1;\n    IMocStateV1 public immutable mocStateV1;\n\n    /**\n     * @notice Constructor\n     * @param mocV1_ The address of the Moc contract.\n     * @param mocStateV1_ The address of the MocState contract.\n     */\n    constructor(address mocV1_, address mocStateV1_) {\n        mocV1 = IMocV1(mocV1_);\n        mocStateV1 = IMocStateV1(mocStateV1_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() external view returns (bool) {\n        return mocStateV1.isLiquidationReached();\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        mocV1.evalLiquidation();\n    }\n}\n\ninterface IMocV1 {\n    function evalLiquidation() external;\n}\n\ninterface IMocStateV1 {\n    function isLiquidationReached() external view returns (bool);\n}"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/token/ERC20/extensions/IERC20Permit.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"},{"file_path":"npm/price-oracle-interfaces@0.1.0/contracts/DocPriceLib.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.24;\n\nimport \"./interfaces/IMocState.sol\";\n\n/// @title DocPriceLib\n/// @notice Helper functions to derive DOC/USD and DOC/RBTC from MoC bucket balances and BTC/USD.\nlibrary DocPriceLib {\n  uint256 internal constant MOC_PRECISION = 1e18;\n  uint256 internal constant MOC_PRECISION_SQUARED = 1e36;\n  bytes32 internal constant BUCKET_C0 = \"C0\";\n\n  /// @notice DOC/USD with 18 decimals. Capped at 1.0 for senior-claim behavior.\n  /// @dev Formula: min(1, (nBTC * BTC/USD) / nDOC)\n  function docUsdPriceSafe(IMocState mocState, uint256 btcPriceInUsd) internal view returns (uint256) {\n    if (btcPriceInUsd == 0) {\n      return 0;\n    }\n\n    uint256 nDoc = mocState.getBucketNDoc(BUCKET_C0);\n    if (nDoc == 0) {\n      return MOC_PRECISION;\n    }\n\n    uint256 nRbtc = mocState.getBucketNBTC(BUCKET_C0);\n    uint256 uncappedDocPriceInUsd = (nRbtc * btcPriceInUsd) / nDoc;\n    return uncappedDocPriceInUsd > MOC_PRECISION ? MOC_PRECISION : uncappedDocPriceInUsd;\n  }\n\n  /// @notice DOC/RBTC with 18 decimals.\n  /// @dev Formula: min(nBTC/nDOC, USD/BTC) where USD/BTC = 1/(BTC/USD).\n  function docRbtcPriceSafe(IMocState mocState, uint256 btcPriceInUsd) internal view returns (uint256) {\n    if (btcPriceInUsd == 0) {\n      return 0;\n    }\n\n    uint256 nDoc = mocState.getBucketNDoc(BUCKET_C0);\n    uint256 usdPerBtc = MOC_PRECISION_SQUARED / btcPriceInUsd;\n    if (nDoc == 0) {\n      return usdPerBtc;\n    }\n\n    uint256 nRbtc = mocState.getBucketNBTC(BUCKET_C0);\n    uint256 bucketDocRbtc = (nRbtc * MOC_PRECISION) / nDoc;\n    return bucketDocRbtc > usdPerBtc ? usdPerBtc : bucketDocRbtc;\n  }\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/governance/Stoppable.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { Governed } from \"./Governed.sol\";\n\n/**\n * @title Stoppable\n * @notice Allow a contract to be paused through the stopper subsystem. This contracts\n * is able to disable the stoppability feature through governance.\n * @dev This contract was heavily based on the _Pausable_ contract of openzeppelin-eth but\n * it was modified in order to being able to turn on and off its stoppability\n */\nabstract contract Stoppable is Governed {\n    event Paused(address account);\n    event Unpaused(address account);\n\n    bool public stoppable;\n    bool private _paused;\n    address public pauser;\n\n    // ------- Custom Errors -------\n    error Unstoppable();\n    error OnlyWhilePaused();\n    error NotWhenPaused();\n    error OnlyPauser();\n\n    /**\n     * @notice Modifier to make a function callable only when the contract is not paused\n     */\n    modifier notPaused() {\n        _checkNotPaused();\n        _;\n    }\n\n    /**\n     * @notice Modifier to make a function callable only when the contract is paused\n     */\n    modifier onlyPaused() {\n        if (!_paused) revert OnlyWhilePaused();\n        _;\n    }\n\n    /**\n     * @notice Initialize the contract with the basic settings\n     * @dev This initialize replaces the constructor but it is not called automatically.\n     * It is necessary because of the upgradeability of the contracts. Either this function or the previous can be used\n     * @param pauserAddress_ The address that is authorized to pause this contract\n     * @param stoppable_ Define if the contract starts being unstoppable or not\n     */\n    function __Stoppable_init_unchained(address pauserAddress_, bool stoppable_) internal onlyInitializing {\n        stoppable = stoppable_;\n        pauser = pauserAddress_;\n    }\n\n    /**\n     * @dev reverts with NotWhenPaused when _paused\n     */\n    function _checkNotPaused() internal view {\n        if (_paused) revert NotWhenPaused();\n    }\n\n    /**\n     * @notice Returns true if paused\n     */\n    function paused() external view returns (bool) {\n        return _paused;\n    }\n\n    /**\n     * @notice Called by the owner to pause, triggers stopped state\n     * @dev Should only be called by the pauser and when it is stoppable\n     */\n    function pause() external notPaused {\n        if (msg.sender != pauser) revert OnlyPauser();\n        if (!stoppable) revert Unstoppable();\n        _paused = true;\n        emit Paused(msg.sender);\n    }\n\n    /**\n     * @notice Called by the owner to unpause, returns to normal state\n     * @dev Should only be called by the pauser and when it is stoppable\n     */\n    function unpause() external onlyPaused {\n        if (msg.sender != pauser && !governor.isAuthorizedChanger(msg.sender)) revert OnlyPauser();\n        if (!stoppable) revert Unstoppable();\n        _paused = false;\n        emit Unpaused(msg.sender);\n    }\n\n    /**\n     * @notice Switches OFF the stoppability of the contract. It cannot be paused or unpaused\n     * Doesn't change the pause state, if the contract was already paused it cannot be operated\n     * @dev Should be called through governance\n     */\n    function makeUnstoppable() external onlyAuthorizedChanger {\n        stoppable = false;\n    }\n\n    /**\n     * @notice Switches ON the stoppability of the contract. It can be paused or unpaused\n     *  Doesn't change the pause state, if the contract was already paused it cannot be operated\n     * @dev Should be called through governance\n     */\n    function makeStoppable() external onlyAuthorizedChanger {\n        stoppable = true;\n    }\n\n    /**\n     * @notice Changes the address which is enable to pause this contract\n     * @param newPauser_ Address of the new pauser\n     * @dev Should be called through governance\n     */\n    function setPauser(address newPauser_) external onlyAuthorizedChanger {\n        // slither-disable-next-line missing-zero-check\n        pauser = newPauser_;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/proxy/ERC1967/ERC1967Proxy.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n    /**\n     * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n     *\n     * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n     * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n     */\n    constructor(address _logic, bytes memory _data) payable {\n        _upgradeToAndCall(_logic, _data, false);\n    }\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _implementation() internal view virtual override returns (address impl) {\n        return ERC1967Upgrade._getImplementation();\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/utils/StorageSlotUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\n * _Available since v4.9 for `string`, `bytes`._\n */\nlibrary StorageSlotUpgradeable {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/utils/math/Math.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1, \"Math: mulDiv overflow\");\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/proxy/Proxy.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n    /**\n     * @dev Delegates the current call to `implementation`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _delegate(address implementation) internal virtual {\n        assembly {\n            // Copy msg.data. We take full control of memory in this inline assembly\n            // block because it will not return to Solidity code. We overwrite the\n            // Solidity scratch pad at memory position 0.\n            calldatacopy(0, 0, calldatasize())\n\n            // Call the implementation.\n            // out and outsize are 0 because we don't know the size yet.\n            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n            // Copy the returned data.\n            returndatacopy(0, 0, returndatasize())\n\n            switch result\n            // delegatecall returns 0 on error.\n            case 0 {\n                revert(0, returndatasize())\n            }\n            default {\n                return(0, returndatasize())\n            }\n        }\n    }\n\n    /**\n     * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n     * and {_fallback} should delegate.\n     */\n    function _implementation() internal view virtual returns (address);\n\n    /**\n     * @dev Delegates the current call to the address returned by `_implementation()`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _fallback() internal virtual {\n        _beforeFallback();\n        _delegate(_implementation());\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n     * function in the contract matches the call data.\n     */\n    fallback() external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n     * is empty.\n     */\n    receive() external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n     * call, or as part of the Solidity `fallback` or `receive` functions.\n     *\n     * If overridden should call `super._beforeFallback()`.\n     */\n    function _beforeFallback() internal virtual {}\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/security/ReentrancyGuardUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    function __ReentrancyGuard_init() internal onlyInitializing {\n        __ReentrancyGuard_init_unchained();\n    }\n\n    function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be _NOT_ENTERED\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _status == _ENTERED;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/utils/math/MathUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1, \"Math: mulDiv overflow\");\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/token/ERC20/extensions/IERC20MetadataUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/core/MocCommons.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocVendors } from \"../vendors/MocVendors.sol\";\nimport { MocEma } from \"./MocEma.sol\";\nimport { IDataProvider } from \"../interfaces/IDataProvider.sol\";\nimport { SignedMath } from \"@openzeppelin/contracts/utils/math/SignedMath.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\n// ------- External Structs -------\n\nstruct PeggedTokenParams {\n    // priceProviderAddress Pegged Token price provider contract address\n    address priceProviderAddress;\n    // Pegged Token target coverage [PREC]\n    uint256 tpCtarg;\n    // additional fee pct applied on mint [PREC]\n    uint256 tpMintFee;\n    // additional fee pct applied on redeem [PREC]\n    uint256 tpRedeemFee;\n    // initial Pegged Token exponential moving average [PREC]\n    uint256 tpEma;\n    // Pegged Token smoothing factor [PREC]\n    uint256 tpEmaSf;\n}\n\n//    +-----------------+\n//    |  MocBaseBucket  |\n//    +-----------------+\n//            ^\n//            | is\n//            |\n//    +-----------------+\n//    |    MocEma       |\n//    +-----------------+\n//            ^\n//            | is\n//            |\n//    +-----------------+ contains  +-----------------+\n//    |    MocCommons   | ------>   |    MocVendors   |\n//    +-----------------+           +-----------------+\n//            ^\n//            | is\n//            | _ _ _ _ _ _ _ _ _ _ _ _ _ _ _\n//            |                              |\n//    +-----------------+ contains  +-----------------+\n//    |     MocCore     | ------>   |MocCoreExpansion |\n//    +-----------------+           +-----------------+\n//            ^\n//            | is\n//            |\n//            |\n//    +-----------------+\n//    |  MocOperations  |\n//    +-----------------+\n//            ^\n//            | is\n//            | _ _ _ _ _ _ _ _ _ _ _ _ _ _ _\n//            |                              |\n//    +-----------------+           +-----------------+\n//    |  MocCACoinbase  |           |    MocCARC20    |\n//    +-----------------+           +-----------------+\n/**\n * @title MocCommons\n * @dev To bypass the 24kb size limitation on MocCore we use MocCoreExpansion contract. Some functions\n *  are implemented there and MocCore delegates calls to it. To achieve that, we need both to have the\n *  exact same storage layout and be able to access the same common functions.\n *  MocCommons contract serves as the last shared ancestor in the line of inheritance for them,\n *  and all storage variables must be either declared here or in a parent contract.\n *  Declaring variables after this point could result in storage collisions.\n */\nabstract contract MocCommons is MocEma {\n    // ------- Storage -------\n\n    // Address for MocVendors contract, provides fee markup information\n    MocVendors public mocVendors;\n\n    // ------- Internal Structs -------\n\n    struct MintTCandTPParams {\n        address tp;\n        uint256 qTP;\n        uint256 qACmax;\n        address sender;\n        address recipient;\n        address vendor;\n    }\n\n    struct RedeemTCandTPParams {\n        address tp;\n        uint256 qTC;\n        uint256 qTP;\n        uint256 qACmin;\n        address sender;\n        address recipient;\n        address vendor;\n    }\n\n    struct SwapTPforTPParams {\n        address tpFrom;\n        address tpTo;\n        uint256 qTP;\n        uint256 qTPmin;\n        uint256 qACmax;\n        address sender;\n        address recipient;\n        address vendor;\n    }\n\n    struct SwapTPforTCParams {\n        address tp;\n        uint256 qTP;\n        uint256 qTCmin;\n        uint256 qACmax;\n        address sender;\n        address recipient;\n        address vendor;\n    }\n\n    struct SwapTCforTPParams {\n        address tp;\n        uint256 qTC;\n        uint256 qTPmin;\n        uint256 qACmax;\n        address sender;\n        address recipient;\n        address vendor;\n    }\n\n    struct RedeemTPParams {\n        address tp;\n        uint256 qTP;\n        uint256 qACmin;\n        address sender;\n        address recipient;\n        address vendor;\n    }\n\n    struct FeeCalcs {\n        uint256 qACFee;\n        uint256 qFeeToken;\n        uint256 qACVendorMarkup;\n        uint256 qFeeTokenVendorMarkup;\n    }\n\n    // ------- Custom Errors -------\n\n    error PeggedTokenAlreadyAdded();\n    error InsufficientTPtoRedeem(uint256 qTP_, uint256 tpAvailableToRedeem_);\n    error TransferFailed();\n    error OnlyWhenLiquidated();\n    error InsufficientQacSent(uint256 qACsent_, uint256 qACNeeded_);\n    error InsufficientTPtoMint(uint256 qTP_, uint256 tpAvailableToMint_);\n    error QtpBelowMinimumRequired(uint256 qTPmin_, uint256 qTP_);\n    error QtcBelowMinimumRequired(uint256 qTCmin_, uint256 qTC_);\n    error QacNeededMustBeGreaterThanZero();\n    error InsufficientTCtoRedeem(uint256 qTC_, uint256 tcAvailableToRedeem_);\n    error MissingProviderData(address dataProviderAddress_);\n    error MaxFluxCapacitorOperationReached(uint256 max_, uint256 new_);\n    error InvalidFluxCapacitorOperation();\n    error InsufficientQtcSent(uint256 qTCsent_, uint256 qTCNeeded_);\n    error QacBelowMinimumRequired(uint256 qACmin_, uint256 qACtoRedeem_);\n    error OnlyWhenLastBucket();\n    error LowCombinedCoverage();\n\n    // ------- Events -------\n\n    event LiqTPRedeemed(\n        address indexed tp_,\n        address indexed sender_,\n        address indexed recipient_,\n        uint256 qTP_,\n        uint256 qAC_\n    );\n    event PeggedTokenChange(uint256 i_, address indexed tpTokenAddress_, PeggedTokenParams peggedTokenParams_);\n\n    // ------- Initializer -------\n\n    /**\n     * @notice contract initializer\n     * @param mocVendors_ address for MocVendors contract.\n     */\n    function __MocCommons_init_unchained(address mocVendors_) internal onlyInitializing {\n        mocVendors = MocVendors(mocVendors_);\n    }\n\n    // ------- Internal Functions -------\n\n    /**\n     * @notice calc fees amount in qAC or Fee Token\n     *  If `sender_` has enough Fee Token to pay fees, will be used. In another case will use qAC\n     * @dev if qFeeToken > 0, qACFee = 0. If qACFee > 0, qFeeToken = 0.\n     * @param sender_ address who executes the operation\n     * @param qAC_ amount of AC involved in the operation, could be sent form sender for mint or\n     *  sent to recipient for redeem [N]\n     * @param qACFeePct_ additional fee pct applied on operation\n     * @return qACSurcharges amount of AC needed to pay fees and markup. 0 if pays with Fee Token\n     * @return feeCalcs\n     * @dev\n     *      qACFee amount of AC needed to pay fees\n     *      qFeeToken amount of Fee Token needed to pay fess\n     *      qACVendorMarkup amount of AC needed to pay vendor markup\n     *      qFeeTokenVendorMarkup amount of Fee Token needed to pay vendor markup\n     */\n    function _calcFees(\n        address sender_,\n        address vendor_,\n        uint256 qAC_,\n        uint256 qACFeePct_\n    ) internal view returns (uint256 qACSurcharges, FeeCalcs memory feeCalcs) {\n        uint256 qFeeTokenTotalNeeded;\n        uint256 qACmarked = 0;\n        if (vendor_ != address(0)) {\n            // [PREC] = [N] * [PREC]\n            qACmarked = qAC_ * mocVendors.vendorMarkup(vendor_);\n        }\n        uint256 senderAllowance = feeToken.allowance(sender_, address(this));\n        if (senderAllowance > 0) {\n            (uint256 feeTokenPrice, bool hasFeeTokenPrice) = _peekPrice(feeTokenPriceProvider);\n            if (hasFeeTokenPrice) {\n                // calculates Fee Token to be charged as fee\n                // [N] = ([N] * [PREC] * [PREC] / [PREC]) / [PREC]\n                feeCalcs.qFeeToken = _mulPrec(qAC_ * qACFeePct_, feeTokenPct) / feeTokenPrice;\n                if (qACmarked > 0) {\n                    // [N] = [PREC] / [PREC]\n                    feeCalcs.qFeeTokenVendorMarkup = qACmarked / feeTokenPrice;\n                    // [N] = [N] + [N]\n                    qFeeTokenTotalNeeded = feeCalcs.qFeeToken + feeCalcs.qFeeTokenVendorMarkup;\n                } else {\n                    qFeeTokenTotalNeeded = feeCalcs.qFeeToken;\n                }\n                if (senderAllowance < qFeeTokenTotalNeeded || feeToken.balanceOf(sender_) < qFeeTokenTotalNeeded) {\n                    feeCalcs.qFeeToken = 0;\n                    feeCalcs.qFeeTokenVendorMarkup = 0;\n                }\n            }\n        }\n        // if sender hasn't got enough feeToken balance or allowance or price provider hasn't got a valid price\n        // then qFeeToken == 0 and sender pays fees with AC\n        // slither-disable-next-line incorrect-equality\n        if (feeCalcs.qFeeToken == 0) {\n            // calculates qAC to be charged as fee\n            // [N] = [N] * [PREC] / [PREC]\n            feeCalcs.qACFee = _mulPrec(qAC_, qACFeePct_);\n            if (qACmarked > 0) {\n                // [N] = [PREC] / [PREC]\n                feeCalcs.qACVendorMarkup = qACmarked / PRECISION;\n                // [N] = [N] + [N]\n                qACSurcharges = feeCalcs.qACFee + feeCalcs.qACVendorMarkup;\n            } else {\n                qACSurcharges = feeCalcs.qACFee;\n            }\n        }\n        return (qACSurcharges, feeCalcs);\n    }\n\n    /**\n     * @notice evaluates if there are enough Pegged Token available to mint, reverts if it`s not\n     * @param qTP_ amount of Pegged Token to mint [N]\n     * @param tpAvailableToMint_ amount of Pegged Token available to mint [N]\n     */\n    function _evalTPavailableToMint(uint256 qTP_, uint256 tpAvailableToMint_) internal pure {\n        // check if there are enough TP available to mint\n        if (tpAvailableToMint_ < qTP_) revert InsufficientTPtoMint(qTP_, tpAvailableToMint_);\n    }\n\n    /**\n     * @notice evaluates if there is enough Collateral Token available to redeem, reverts if there's not\n     * @param qTC_ amount of Collateral Token to redeem [N]\n     * @param tcAvailableToRedeem_ amount of Collateral Token available to redeem [N]\n     */\n    function _evalTCAvailableToRedeem(uint256 qTC_, uint256 tcAvailableToRedeem_) internal pure {\n        // check if there are enough TC available to redeem\n        if (tcAvailableToRedeem_ < qTC_) revert InsufficientTCtoRedeem(qTC_, tcAvailableToRedeem_);\n    }\n\n    /**\n     * @notice ask to oracles for flux capacitor settings\n     * @return absolute maximum transaction allowed for a certain number of seconds\n     * @return differential maximum transaction allowed for a certain number of seconds\n     */\n    function _peekFluxCapacitorSettings() internal view returns (uint256, uint256) {\n        bytes32 maxAbsoluteOp;\n        bytes32 maxOpDiff;\n        bool has;\n        // get max absolute operation\n        IDataProvider dataProvider = maxAbsoluteOpProvider;\n        (maxAbsoluteOp, has) = dataProvider.peek();\n        if (!has) revert MissingProviderData(address(dataProvider));\n        // get max operational difference\n        dataProvider = maxOpDiffProvider;\n        (maxOpDiff, has) = dataProvider.peek();\n        if (!has) revert MissingProviderData(address(dataProvider));\n        return (uint256(maxAbsoluteOp), uint256(maxOpDiff));\n    }\n\n    /**\n     * @notice returns lineal decay factor\n     * @param timeSpan_ amount of seconds to ask for the decay\n     * @return newAbsoluteAccumulator absolute accumulator updated by lineal decay factor [N]\n     * @return newDifferentialAccumulator differential accumulator updated by lineal decay factor [N]\n     */\n    function _calcAccWithDecayFactor(\n        uint256 timeSpan_\n    ) internal view returns (uint256 newAbsoluteAccumulator, int256 newDifferentialAccumulator) {\n        // [N] = [N] - [N]\n        uint256 timeElapsed = block.timestamp + timeSpan_ - lastOperationTimeStamp;\n        // [PREC] = [N] * [PREC] / [N]\n        uint256 timeRatio = (timeElapsed * PRECISION) / decayTimeSpan;\n        if (timeRatio >= ONE) return (0, 0);\n        uint256 decayFactor = ONE - timeRatio;\n        // [N] = [N] * [PREC] / [PREC]\n        newAbsoluteAccumulator = (absoluteAccumulator * decayFactor) / PRECISION;\n        // [N] = [N] * [PREC] / [PREC]\n        newDifferentialAccumulator = (differentialAccumulator * int256(decayFactor)) / int256(PRECISION);\n        return (newAbsoluteAccumulator, newDifferentialAccumulator);\n    }\n\n    /**\n     * @notice indicates whether or not Flux Capacitor is enabled\n     * @dev decayTimeSpan zero, is used as an indicator that the FC tracking and\n     * validations will not apply.\n     */\n    function _isFluxCapacitorEnabled() internal view returns (bool) {\n        return decayTimeSpan != 0;\n    }\n\n    /**\n     * @notice common function used to update accumulators during a TP operation\n     *  reverts if not allowed\n     * @dev the only difference between a redeem and a mint operation is that in the first one,\n     * the qAC is subtracted on newDifferentialAccumulator instead of added\n     * @param qAC_ amount of Collateral Asset used to mint\n     * @param redeemFlag_ true if it is a redeem TP operation\n     */\n    function _updateAccumulators(uint256 qAC_, bool redeemFlag_) internal {\n        if (!_isFluxCapacitorEnabled()) return;\n\n        (uint256 maxAbsoluteOperation, uint256 maxOperationalDifference) = _peekFluxCapacitorSettings();\n        (uint256 newAbsoluteAccumulator, int256 newDifferentialAccumulator) = _calcAccWithDecayFactor(0);\n        unchecked {\n            newAbsoluteAccumulator += qAC_;\n            int256 qACInt = int256(qAC_);\n            if (redeemFlag_) qACInt = -qACInt;\n            newDifferentialAccumulator += qACInt;\n            // cannot underflow, always newDifferentialAccumulator <= newAbsoluteAccumulator\n            uint256 operationalDifference = newAbsoluteAccumulator - SignedMath.abs(newDifferentialAccumulator);\n            if (newAbsoluteAccumulator > maxAbsoluteOperation) {\n                if (qAC_ > maxAbsoluteOperation) revert InvalidFluxCapacitorOperation();\n                revert MaxFluxCapacitorOperationReached(maxAbsoluteOperation, newAbsoluteAccumulator);\n            }\n            if (operationalDifference > maxOperationalDifference)\n                revert MaxFluxCapacitorOperationReached(maxOperationalDifference, operationalDifference);\n            // update storage\n            absoluteAccumulator = newAbsoluteAccumulator;\n            differentialAccumulator = newDifferentialAccumulator;\n            lastOperationTimeStamp = block.timestamp;\n        }\n    }\n\n    /**\n     * @notice update accumulators during a mint TP operation\n     *  reverts if not allowed\n     * @param qAC_ amount of Collateral Asset used to mint\n     */\n    function _updateAccumulatorsOnMintTP(uint256 qAC_) internal {\n        _updateAccumulators(qAC_, false);\n    }\n\n    /**\n     * @notice update accumulators during a redeem operation\n     *  reverts if not allowed\n     * @param qAC_ reserve amount used for redeem\n     */\n    function _updateAccumulatorsOnRedeemTP(uint256 qAC_) internal {\n        _updateAccumulators(qAC_, true);\n    }\n\n    /**\n     * @notice internal common function used to calc max AC allowed to mint or redeem TP\n     *  due to accumulators\n     * @param newAbsoluteAccumulator_ absolute accumulator updated by lineal decay factor [N]\n     * @param a_ on mint = AA - DA ; on redeem = AA + DA\n     * @param b_ on mint = AA + DA ; on redeem = AA - DA\n     * @return maxQAC minimum regarding maxAbsoluteOperation and maxOperationalDifference\n     */\n    function _calcMaxQACToOperateTP(\n        uint256 newAbsoluteAccumulator_,\n        uint256 a_,\n        uint256 b_\n    ) internal view returns (uint256 maxQAC) {\n        (uint256 maxAbsoluteOperation, uint256 maxOperationalDifference) = _peekFluxCapacitorSettings();\n        if (newAbsoluteAccumulator_ >= maxAbsoluteOperation) return 0;\n        uint256 absoluteAccAllowed = maxAbsoluteOperation - newAbsoluteAccumulator_;\n\n        if (a_ <= maxOperationalDifference) return absoluteAccAllowed;\n        if (b_ >= maxOperationalDifference) return 0;\n        uint256 differentialAccAllowed = (maxOperationalDifference - b_) / 2;\n        return Math.min(absoluteAccAllowed, differentialAccAllowed);\n    }\n\n    /**\n     * @notice gets the max amount of AC allowed to operate to mint TP with, restricted by accumulators\n     * @param timeSpan_ amount of seconds to project the decay into the future\n     * @return maxQAC minimum regarding maxAbsoluteOperation and maxOperationalDifference\n     */\n    function maxQACToMintTP(uint256 timeSpan_) external view returns (uint256 maxQAC) {\n        // If FC is disabled, there is no protocol limit to the amount to be operated\n        if (!_isFluxCapacitorEnabled()) {\n            return UINT256_MAX;\n        }\n        (uint256 newAbsoluteAccumulator, int256 newDifferentialAccumulator) = _calcAccWithDecayFactor(timeSpan_);\n        // X = mint amount\n        // (AA + X) - |DA + X| <= MODA && X >= 0\n        // 1) if DA + X >= 0 ---> AA + X - DA - X <= MODA ---> AA - DA <= MODA\n        // 2) if DA + X < 0 ---> X <= (MODA - (AA + DA)) / 2\n\n        // AA >= |DA|\n        uint256 a = uint256(int256(newAbsoluteAccumulator) - newDifferentialAccumulator);\n        uint256 b = uint256(int256(newAbsoluteAccumulator) + newDifferentialAccumulator);\n        return _calcMaxQACToOperateTP(newAbsoluteAccumulator, a, b);\n    }\n\n    /**\n     * @notice gets the max amount of AC allowed to operate to redeem TP with, restricted by accumulators\n     * @param timeSpan_ amount of seconds to project the decay into the future\n     * @return maxQAC minimum regarding maxAbsoluteOperation and maxOperationalDifference\n     */\n    function maxQACToRedeemTP(uint256 timeSpan_) external view returns (uint256 maxQAC) {\n        // If FC is disabled, there is no protocol limit to the amount to be operated\n        if (!_isFluxCapacitorEnabled()) {\n            return UINT256_MAX;\n        }\n        (uint256 newAbsoluteAccumulator, int256 newDifferentialAccumulator) = _calcAccWithDecayFactor(timeSpan_);\n        // X = redeem amount\n        // (AA + X) - |DA - X| <= MODA && X >= 0\n        // 1) if DA - X < 0 ---> AA + X + DA - X <= MODA ---> AA + DA <= MODA\n        // 2) if DA - X >= 0 ---> X <= (MODA - (AA - DA)) / 2\n\n        // AA >= |DA|\n        uint256 a = uint256(int256(newAbsoluteAccumulator) + newDifferentialAccumulator);\n        uint256 b = uint256(int256(newAbsoluteAccumulator) - newDifferentialAccumulator);\n        return _calcMaxQACToOperateTP(newAbsoluteAccumulator, a, b);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/interfaces/IChangeContract.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\n/**\n  @title IChangeContract\n  @notice This interface is the one used by the governance system.\n  @dev If you plan to do some changes to a system governed by this project you should write a contract\n  that does those changes, like a recipe. This contract MUST not have ANY kind of public or external function\n  that modifies the state of this ChangeContract, otherwise you could run into front-running issues when the governance\n  system is fully in place.\n */\ninterface IChangeContract {\n    /**\n    @notice Override this function with a recipe of the changes to be done when this ChangeContract\n    is executed\n   */\n    function execute() external;\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/oracles/TaskSwitchRoundCoinPair.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../ITask.sol\";\n\n/**\n * @title TaskSwitchRoundCoinPair\n * @notice This contract implements a task that switches the round for a coin pair.\n */\ncontract TaskSwitchRoundCoinPair is ITask {\n    error TaskNotAvailable();\n    ICoinPair public immutable coinPair;\n\n    /**\n     * @notice Constructor\n     * @param coinPair_ The address of the CoinPair contract.\n     */\n    constructor(address coinPair_) {\n        coinPair = ICoinPair(coinPair_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() external view returns (bool) {\n        return isReadyToSwitchRound(coinPair);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        coinPair.switchRound();\n    }\n\n    /**\n     * @notice Check if a coin pair is ready to switch rounds.\n     * @param coinPair_ The coin pair to check.\n     * @return True if the coin pair is ready to switch rounds, false otherwise.\n     */\n    function isReadyToSwitchRound(ICoinPair coinPair_) public view returns (bool) {\n        (uint256 round, , uint256 lockPeriodTimestamp, , , ) = coinPair_.getRoundInfo();\n        return block.timestamp > lockPeriodTimestamp && round != 0;\n    }\n}\n\ninterface ICoinPair {\n    /// @notice Switch contract context to a new round. With the objective of\n    /// being a decentralized solution, this can be called by *anyone* if current\n    /// round lock period is expired.\n    /// This method search the subscribed list and choose the 10 with more stake.\n    function switchRound() external;\n\n    /// @notice Return current round information\n    function getRoundInfo()\n        external\n        view\n        returns (\n            uint256 round,\n            uint256 startBlock,\n            uint256 lockPeriodTimestamp,\n            uint256 totalPoints,\n            address[] memory selectedOwners,\n            address[] memory selectedOracles\n        );\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/multiCollateral/swapper/MocSwapperV3MultiHop.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocUpgradable } from \"../../governance/MocUpgradable.sol\";\nimport { IMocSwapper } from \"../../interfaces/IMocSwapper.sol\";\nimport { IWrapper } from \"../../interfaces/IWrapper.sol\";\nimport { IV3SwapRouter } from \"@uniswap/swap-router-contracts/contracts/interfaces/IV3SwapRouter.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { IDataProvider } from \"../../interfaces/IDataProvider.sol\";\n\n/**\n * @title MocSwapperV3MultiHop\n * @notice MocSwapper component to swap tokens using uniswapV3 protocol\n *\n */\ncontract MocSwapperV3MultiHop is IMocSwapper, MocUpgradable {\n    address private constant COINBASE = address(0);\n    // ------- Custom Errors -------\n    error WrongLength();\n    error CoinbaseTransferFailed();\n    error PartialSwap();\n\n    // ------- Storage -------\n    // uniswapV3 router contracts\n    IV3SwapRouter public swapRouter;\n    // coinbase RC20 wrapper. Used to swap coinbase on the exchange\n    IWrapper public coinbaseWrapper;\n    // tokenIn => tokenOut => path\n    mapping(address tokenIn => mapping(address tokenOut => bytes path)) public encodedPaths;\n    // this is used to limit the amount of tokens that can be swapped in a single operation\n    mapping(address tokenIn => mapping(address tokenOut => IDataProvider maxAmountToSwapProvider))\n        public maxAmountToSwapProviders;\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    /**\n     * @notice @notice contract initializer\n     * @param governorAddress_ address of the governor contract\n     * @param pauserAddress_ address of the pauser contract\n     * @param swapRouter_ address of the uniswapV3 router\n     * @param coinbaseWrapper_ address of the coinbase wrapper\n     */\n    function initialize(\n        address governorAddress_,\n        address pauserAddress_,\n        address swapRouter_,\n        address coinbaseWrapper_\n    ) external initializer {\n        __MocUpgradable_init(governorAddress_, pauserAddress_);\n        swapRouter = IV3SwapRouter(swapRouter_);\n        coinbaseWrapper = IWrapper(coinbaseWrapper_);\n    }\n\n    /**\n     * @inheritdoc IMocSwapper\n     */\n    function getSafeMaxAmountToSwap(address tokenIn_, address tokenOut_) public view returns (uint256) {\n        (bytes32 maxAmountToSwap, bool has) = maxAmountToSwapProviders[tokenIn_][tokenOut_].peek();\n        if (!has) revert MissingProviderData(address(maxAmountToSwapProviders[tokenIn_][tokenOut_]));\n        return uint256(maxAmountToSwap);\n    }\n\n    /**\n     * @inheritdoc IMocSwapper\n     */\n    function swapCoinbase(\n        address tokenOut_,\n        uint256 amountOutMin_,\n        address recipient_\n    ) external payable returns (uint256 amountOut) {\n        coinbaseWrapper.deposit{ value: msg.value }();\n        return _swapExactInput(COINBASE, tokenOut_, msg.value, amountOutMin_, recipient_);\n    }\n\n    /**\n     * @inheritdoc IMocSwapper\n     */\n    function swapCoinbaseExactOutput(\n        address tokenOut_,\n        uint256 amountOut_,\n        address recipient_\n    ) external payable returns (uint256 amountIn) {\n        coinbaseWrapper.deposit{ value: msg.value }();\n        amountIn = _swapExactOutput(COINBASE, tokenOut_, amountOut_, msg.value, recipient_);\n        // return excess coinbase\n        if (msg.value > amountIn) {\n            _unwrapAndTransfer(msg.value - amountIn, msg.sender);\n        }\n    }\n\n    /**\n     * @inheritdoc IMocSwapper\n     */\n    function swapRC20(\n        address tokenIn_,\n        address tokenOut_,\n        uint256 amountIn_,\n        uint256 amountOutMin_,\n        address recipient_\n    ) external returns (uint256 amountOut) {\n        SafeERC20.safeTransferFrom(IERC20(tokenIn_), msg.sender, address(this), amountIn_);\n        bool unwrap = tokenOut_ == address(0);\n        amountOut = _swapExactInput(tokenIn_, tokenOut_, amountIn_, amountOutMin_, unwrap ? address(this) : recipient_);\n\n        if (unwrap) {\n            _unwrapAndTransfer(amountOut, recipient_);\n        }\n    }\n\n    /**\n     * @inheritdoc IMocSwapper\n     */\n    function swapRC20ExactOutput(\n        address tokenIn_,\n        address tokenOut_,\n        uint256 amountOut_,\n        uint256 amountInMax_,\n        address recipient_\n    ) external returns (uint256 amountIn) {\n        SafeERC20.safeTransferFrom(IERC20(tokenIn_), msg.sender, address(this), amountInMax_);\n        bool unwrap = tokenOut_ == address(0);\n        amountIn = _swapExactOutput(tokenIn_, tokenOut_, amountOut_, amountInMax_, unwrap ? address(this) : recipient_);\n        // return excess tokenIn\n        if (amountInMax_ > amountIn) {\n            // reset allowance to zero\n            SafeERC20.forceApprove(IERC20(tokenIn_), address(swapRouter), 0);\n            SafeERC20.safeTransfer(IERC20(tokenIn_), msg.sender, amountInMax_ - amountIn);\n        }\n\n        if (unwrap) {\n            _unwrapAndTransfer(amountOut_, recipient_);\n        }\n    }\n\n    /**\n     * @notice swap RC20 token using exact input\n     * @param tokenIn_ RC20 token to send. If address(0) use the coinbase wrapper\n     * @param tokenOut_ RC20 token to receive. If address(0) use the coinbase wrapper\n     * @param amountIn_ amount of tokens to swap\n     * @param amountOutMin_ minimum amount of tokens to receive\n     * @param recipient_ address who receives the tokens\n     * @return amountOut amount of RC20 tokens received\n     */\n    function _swapExactInput(\n        address tokenIn_,\n        address tokenOut_,\n        uint256 amountIn_,\n        uint256 amountOutMin_,\n        address recipient_\n    ) internal returns (uint256 amountOut) {\n        address tokenIn = tokenIn_ == COINBASE ? address(coinbaseWrapper) : tokenIn_;\n        SafeERC20.forceApprove(IERC20(tokenIn), address(swapRouter), amountIn_);\n        IV3SwapRouter.ExactInputParams memory params = IV3SwapRouter.ExactInputParams({\n            path: encodedPaths[tokenIn_][tokenOut_],\n            recipient: recipient_,\n            amountIn: amountIn_,\n            amountOutMinimum: amountOutMin_\n        });\n\n        uint256 balanceBefore = IERC20(tokenIn).balanceOf(address(this));\n\n        // Execute the swap\n        amountOut = swapRouter.exactInput(params);\n\n        if (IERC20(tokenIn).balanceOf(address(this)) != balanceBefore - amountIn_) revert PartialSwap();\n    }\n\n    /**\n     * @notice swap RC20 token method using exact output\n     * @param tokenIn_ RC20 token to send. If address(0) use the coinbase wrapper\n     * @param tokenOut_ RC20 token to receive. If address(0) use the coinbase wrapper\n     * @param amountOut_ amount of tokens to receive in the swap\n     * @param amountInMax_ maximum amount of tokens to spend\n     * @param recipient_ address who receives the tokens\n     * @return amountIn amount of RC20 tokens spent\n     */\n    function _swapExactOutput(\n        address tokenIn_,\n        address tokenOut_,\n        uint256 amountOut_,\n        uint256 amountInMax_,\n        address recipient_\n    ) internal returns (uint256 amountIn) {\n        address tokenIn = tokenIn_ == COINBASE ? address(coinbaseWrapper) : tokenIn_;\n        address tokenOut = tokenOut_ == COINBASE ? address(coinbaseWrapper) : tokenOut_;\n        SafeERC20.forceApprove(IERC20(tokenIn), address(swapRouter), amountInMax_);\n        IV3SwapRouter.ExactOutputParams memory params = IV3SwapRouter.ExactOutputParams({\n            path: encodedPaths[tokenOut_][tokenIn_], // reversed path for exact output\n            recipient: recipient_,\n            amountOut: amountOut_,\n            amountInMaximum: amountInMax_\n        });\n\n        uint256 balanceBefore = IERC20(tokenOut).balanceOf(recipient_);\n\n        // Execute the swap\n        amountIn = swapRouter.exactOutput(params);\n\n        // NOTICE: When using a standard Uniswap Router, exactOutput reverts before this does.\n        // but we keep this here defensively, it's worth the gas.\n        if (IERC20(tokenOut).balanceOf(recipient_) != balanceBefore + amountOut_) revert PartialSwap();\n    }\n\n    /**\n     * @notice Unwrap coinbase and transfer to recipient\n     * @param amount Amount to unwrap and transfer\n     * @param recipient Recipient address\n     */\n    function _unwrapAndTransfer(uint256 amount, address recipient) internal {\n        coinbaseWrapper.withdraw(amount);\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, ) = address(recipient).call{ value: amount }(\"\");\n        if (!success) revert CoinbaseTransferFailed();\n    }\n\n    // ------- Only Authorized Changer Functions -------\n    /**\n     * @notice sets a new path to the swapper\n     * @dev for example, if tokenA = WETH, tokenB = USDC, intermediateTokens = [DOC, USDT], fees = [3000, 500, 500]\n     * the path will be: WETH -> DOC (3000) -> USDT (500) -> USDC (500)\n     * @param tokenA_ address of the first token\n     * @param tokenB_ address of the second token\n     * @param intermediateTokens_ array of intermediate tokens\n     * @param fees_ array of fees for each intermediate token\n     * @param providerSwappingAtoB_ address of the max amount to swap provider for the tokenA -> tokenB pool\n     */\n    function setPath(\n        address tokenA_,\n        address tokenB_,\n        address[] memory intermediateTokens_,\n        uint24[] memory fees_,\n        IDataProvider providerSwappingAtoB_\n    ) external onlyAuthorizedChanger {\n        if (fees_.length != intermediateTokens_.length + 1) revert WrongLength();\n\n        address tokenA = tokenA_ == COINBASE ? address(coinbaseWrapper) : tokenA_;\n        address tokenB = tokenB_ == COINBASE ? address(coinbaseWrapper) : tokenB_;\n\n        // path: tokenA -> intermediates -> tokenB\n        bytes memory path = abi.encodePacked(tokenA);\n        for (uint256 i = 0; i < intermediateTokens_.length; i++) {\n            path = bytes.concat(path, abi.encodePacked(fees_[i], intermediateTokens_[i]));\n        }\n        path = bytes.concat(path, abi.encodePacked(fees_[fees_.length - 1], tokenB));\n\n        encodedPaths[tokenA_][tokenB_] = path;\n        maxAmountToSwapProviders[tokenA_][tokenB_] = providerSwappingAtoB_;\n    }\n\n    // @notice used to receive coinbase to unwrap it\n    receive() external payable {}\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/core/MocCore.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocCommons, PeggedTokenParams, MocVendors } from \"./MocCommons.sol\";\nimport { MocCoreExpansion } from \"./MocCoreExpansion.sol\";\nimport { IMocRC20 } from \"../interfaces/IMocRC20.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\n/**\n * @title MocCore\n * @notice MocCore nucleates all the basic MoC functionality and tool set. It allows Collateral\n * asset aware contracts to implement the main mint/redeem operations.\n */\nabstract contract MocCore is MocCommons {\n    // ------- Events -------\n    event SuccessFeeDistributed(uint256 mocGain_, uint256[] tpGain_);\n    event SettlementExecuted();\n    event TCInterestPayment(uint256 interestAmount_);\n    // ------- Custom Errors -------\n    error MissingTimeToSettlement();\n    error MissingTimeToTCInterestPayment();\n    // ------- Structs -------\n\n    struct InitializeCoreParams {\n        InitializeBaseBucketParams initializeBaseBucketParams;\n        // The address that will define when a change contract is authorized\n        address governorAddress;\n        // The address that is authorized to pause this contract\n        address pauserAddress;\n        // Moc Core Expansion contract address\n        address mocCoreExpansion;\n        // amount of seconds to wait between Pegged ema calculation\n        uint256 emaCalculationTimeSpan;\n        // address for MocVendors\n        address mocVendors;\n    }\n\n    // ------- Storage -------\n    // Moc Core Expansion contract address, used to expand 24kb size limit\n    address internal mocCoreExpansion;\n\n    // ------- Initializer -------\n    /**\n     * @notice contract initializer\n     * @dev this function must be execute by the AC implementation at initialization\n     * @param initializeCoreParams_ contract initializer params\n     *        governorAddress The address that will define when a change contract is authorized\n     *        pauserAddress_ The address that is authorized to pause this contract\n     *        mocCoreExpansion Moc Core Expansion contract address\n     *        mocQueueAddress address for MocQueue contract\n     *        feeTokenAddress Fee Token contract address\n     *        feeTokenPriceProviderAddress Fee Token price provider contract address\n     *        tcTokenAddress Collateral Token contract address\n     *        mocFeeFlowAddress Moc Fee Flow contract address\n     *        mocAppreciationBeneficiaryAddress Moc appreciation beneficiary address\n     *        protThrld protected state threshold [PREC]\n     *        liqThrld liquidation coverage threshold [PREC]\n     *        feeRetainer pct retain on fees to be re-injected as Collateral, while paying fees with AC [PREC]\n     *        tcMintFee additional fee pct applied on mint Collateral Tokens operations [PREC]\n     *        tcRedeemFee additional fee pct applied on redeem Collateral Tokens operations [PREC]\n     *        swapTPforTPFee additional fee pct applied on swap a Pegged Token for another Pegged Token [PREC]\n     *        swapTPforTCFee additional fee pct applied on swap a Pegged Token for Collateral Token [PREC]\n     *        swapTCforTPFee additional fee pct applied on swap Collateral Token for a Pegged Token [PREC]\n     *        redeemTCandTPFee additional fee pct applied on redeem Collateral Token and Pegged Token [PREC]\n     *        mintTCandTPFee additional fee pct applied on mint Collateral Token and Pegged Token [PREC]\n     *        feeTokenPct pct applied on the top of the operation`s fee when using\n     *          Fee Token as fee payment method [PREC]\n     *        successFee pct of the gain because Pegged Tokens devaluation that is transferred\n     *          in Collateral Asset to Moc Fee Flow during the settlement [PREC]\n     *        appreciationFactor pct of the gain because Pegged Tokens devaluation that is returned\n     *          in Pegged Tokens to appreciation beneficiary during the settlement [PREC]]\n     *        settlementTimeSpan time between settlements\n     *        tcInterestCollectorAddress TC interest collector address\n     *        tcInterestRate pct interest charged to TC holders on the total collateral in the protocol [PREC]\n     *        tcInterestPaymentTimeSpan amount of seconds to wait for next TC interest payment\n     *        maxAbsoluteOpProviderAddress max absolute operation provider address\n     *        maxOpDiffProviderAddress max operation difference provider address\n     *        decayTimeSpan number of seconds that have to elapse for the linear decay factor to be 0\n     *        emaCalculationTimeSpan amount of seconds to wait between Pegged ema calculation\n     *        mocVendors address for MocVendors contract.\n     */\n    function __MocCore_init(InitializeCoreParams calldata initializeCoreParams_) internal onlyInitializing {\n        mocCoreExpansion = initializeCoreParams_.mocCoreExpansion;\n        __MocUpgradable_init(initializeCoreParams_.governorAddress, initializeCoreParams_.pauserAddress);\n        __MocBaseBucket_init_unchained(initializeCoreParams_.initializeBaseBucketParams);\n        __MocEma_init_unchained(initializeCoreParams_.emaCalculationTimeSpan);\n        __MocCommons_init_unchained(initializeCoreParams_.mocVendors);\n    }\n\n    // ------- Internal abstract Functions -------\n\n    /**\n     * @notice transfer Collateral Asset\n     * @dev this function must be overridden by the AC implementation\n     *  and revert if transfer fails.\n     * IMPORTANT: if ac transfer could trigger custom gas consumption for the Collateral\n     * used (like coinbase fallback or ERC777), gasLimit should be capped\n     * @param to_ address who receives the Collateral Asset\n     * @param amount_ amount of Collateral Asset to transfer\n     */\n    function acTransfer(address to_, uint256 amount_) internal virtual;\n\n    /**\n     * @notice Collateral Asset balance\n     * @dev this function must be overridden by the AC implementation\n     * @param account address who's Collateral Asset balance we want to know of\n     * @return balance `account`'s total amount of Collateral Asset\n     */\n    function acBalanceOf(address account) internal view virtual returns (uint256 balance);\n\n    /**\n     * @notice Collateral Asset token address. address(0) for coinbase\n     * @dev this function must be overridden by the AC implementation\n     * @return acToken Collateral Asset token address. address(0) for coinbase\n     */\n    function acToken() external view virtual returns (address acToken);\n\n    /**\n     * @notice Refreshes the AC holdings for the Bucket\n     * @dev Intended to be use as notification after an RC20 AC transfer to this contract\n     *   this function must be overridden by the AC implementation\n     */\n    function refreshACBalance() external virtual;\n\n    // ------- Internal Functions -------\n\n    struct MintTCParams {\n        uint256 qTC;\n        uint256 qACmax;\n        address sender;\n        address recipient;\n        address vendor;\n    }\n\n    /**\n     * @notice mint Collateral Token in exchange for Collateral Asset\n     * @param params_ mintTCto function params\n     * @dev\n     *      qTC_ amount of Collateral Token to mint\n     *      qACmax_ maximum amount of Collateral Asset that can be spent\n     *      sender_ address who sends the Collateral Asset, all unspent amount is returned to it\n     *      recipient_ address who receives the Collateral Token\n     *      vendor_ address who receives a markup. If its address(0) no markup is applied\n     * @return qACtotalNeeded amount of AC used to mint qTC\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function _mintTCto(\n        MintTCParams memory params_\n    ) internal notLiquidated notPaused returns (uint256 qACtotalNeeded, FeeCalcs memory feeCalcs) {\n        uint256[] memory pACtps = _getPACtps();\n        // evaluates whether or not the system coverage is healthy enough to mint TC, reverts if it's not\n        (uint256 lckAC, uint256 nACgain) = _evalCoverage(protThrld, pACtps);\n        // calculates how many qAC are needed to mint TC\n        // [N] = [N] * [PREC] / [PREC]\n        uint256 qACNeededToMint = _mulPrec(params_.qTC, _getPTCac(lckAC, nACgain));\n        uint256 qACSurcharges;\n        (qACSurcharges, feeCalcs) = _calcFees(params_.sender, params_.vendor, qACNeededToMint, tcMintFee);\n        qACtotalNeeded = qACNeededToMint + qACSurcharges;\n        if (qACtotalNeeded > params_.qACmax) revert InsufficientQacSent(params_.qACmax, qACtotalNeeded);\n        // if is 0 reverts because it is trying to redeem an amount below precision\n        // slither-disable-next-line incorrect-equality\n        if (qACtotalNeeded == 0) revert QacNeededMustBeGreaterThanZero();\n        _depositAndMintTC(params_.qTC, qACNeededToMint, params_.recipient);\n        // All locked AC is either unlock or returned, no longer on pending Operation\n        qACLockedInPending -= params_.qACmax;\n        // transfers any AC change to the sender and distributes fees\n        _distOpResults(params_.sender, params_.sender, params_.qACmax - qACtotalNeeded, params_.vendor, feeCalcs);\n    }\n\n    struct RedeemTCParams {\n        uint256 qTC;\n        uint256 qACmin;\n        address sender;\n        address recipient;\n        address vendor;\n    }\n\n    /**\n     * @notice redeem Collateral Asset in exchange for Collateral Token\n     * @param params_ redeemTCto function params\n     * @dev\n     *      qTC_ amount of Collateral Token to redeem\n     *      qACmin_ minimum amount of Collateral Asset that `recipient_` expects to receive\n     *      sender_ address who sends the Collateral Token\n     *      recipient_ address who receives the Collateral Asset\n     *      vendor_ address who receives a markup. If its address(0) no markup is applied\n     * @return qACtoRedeem amount of AC sent to `recipient_`\n     * @return feeCalcs platform fee detail breakdown\n     */\n\n    function _redeemTCto(\n        RedeemTCParams memory params_\n    ) internal notLiquidated notPaused returns (uint256 qACtoRedeem, FeeCalcs memory feeCalcs) {\n        // emas are updated here and multi collateral status evaluated, reverts if it is not healthy enough\n        (uint256 tcAvailableToRedeem, uint256[] memory pACtps) = _getMocMultiCollateralGuard().getCombinedAndTC(\n            address(this)\n        );\n\n        uint256 ctargemaCA = _calcCtargemaCA(pACtps);\n        // evaluates whether or not the system coverage is healthy enough to redeem TC\n        // given the target coverage adjusted by the moving average, reverts if it's not\n        (uint256 lckAC, uint256 nACgain) = _evalCoverage(ctargemaCA, pACtps);\n        // evaluates if there are enough Collateral Tokens available to redeem, reverts if there are not\n        _evalTCAvailableToRedeem(params_.qTC, tcAvailableToRedeem);\n        // calculate how many total qAC are redeemed\n        // [N] = [N] * [PREC] / [PREC]\n        uint256 qACtotalToRedeem = _mulPrec(params_.qTC, _getPTCac(lckAC, nACgain));\n        // if is 0 reverts because it is trying to redeem an amount below precision\n        // slither-disable-next-line incorrect-equality\n        if (qACtotalToRedeem == 0) revert QacNeededMustBeGreaterThanZero();\n        uint256 qACSurcharges;\n        (qACSurcharges, feeCalcs) = _calcFees(params_.sender, params_.vendor, qACtotalToRedeem, tcRedeemFee);\n        qACtoRedeem = qACtotalToRedeem - qACSurcharges;\n        if (qACtoRedeem < params_.qACmin) revert QacBelowMinimumRequired(params_.qACmin, qACtoRedeem);\n        _withdrawAndBurnTC(params_.qTC, qACtotalToRedeem);\n        // transfers qAC to the recipient and distributes fees\n        _distOpResults(params_.sender, params_.recipient, qACtoRedeem, params_.vendor, feeCalcs);\n    }\n\n    struct MintTPParams {\n        address tp;\n        uint256 qTP;\n        uint256 qACmax;\n        address sender;\n        address recipient;\n        address vendor;\n    }\n\n    /**\n     * @notice mint Pegged Token in exchange for Collateral Asset\n     * @param params_ mint TP function params\n     * @dev\n     *      i_ Pegged Token index\n     *      qTP_ amount of Pegged Token to mint\n     *      qACmax_ maximum amount of Collateral Asset that can be spent\n     *      sender_ address who sends the Collateral Asset, all unspent amount is returned to it\n     *      recipient_ address who receives the Pegged Token\n     *      vendor_ address who receives a markup. If its address(0) no markup is applied\n     * @return qACtotalNeeded amount of AC used to mint qTP\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function _mintTPto(\n        MintTPParams memory params_\n    ) internal notLiquidated notPaused returns (uint256 qACtotalNeeded, FeeCalcs memory feeCalcs) {\n        // emas are updated here and multi collateral status evaluated, reverts if it is not healthy enough\n        (uint256 tpAvailableToMint, uint256[] memory pACtps) = _getMocMultiCollateralGuard().getCombinedAndTP(\n            address(this),\n            params_.tp\n        );\n\n        uint256 ctargemaCA = _calcCtargemaCA(pACtps);\n        uint256 i = _tpi(params_.tp);\n        uint256 pACtp = pACtps[i];\n        _updateTPtracking(i, pACtp);\n        // evaluates whether or not the system coverage is healthy enough to mint TP\n        // given the target coverage adjusted by the moving average, reverts if it's not\n        _evalCoverage(ctargemaCA, pACtps);\n        // evaluates if there are enough TP available to mint, reverts if it's not\n        _evalTPavailableToMint(params_.qTP, tpAvailableToMint);\n        // calculate how many qAC are needed to mint TP\n        // [N] = [N] * [PREC] / [PREC]\n        uint256 qACNeededtoMint = _divPrec(params_.qTP, pACtp);\n        uint256 qACSurcharges;\n        (qACSurcharges, feeCalcs) = _calcFees(params_.sender, params_.vendor, qACNeededtoMint, tpMintFees[params_.tp]);\n        qACtotalNeeded = qACNeededtoMint + qACSurcharges;\n        if (qACtotalNeeded > params_.qACmax) revert InsufficientQacSent(params_.qACmax, qACtotalNeeded);\n        // if is 0 reverts because it is trying to mint an amount below precision\n        // slither-disable-next-line incorrect-equality\n        if (qACtotalNeeded == 0) revert QacNeededMustBeGreaterThanZero();\n        // update flux capacitor and reverts if not allowed by accumulators\n        _updateAccumulatorsOnMintTP(qACNeededtoMint);\n        // update bucket and mint\n        _depositAndMintTP(i, params_.qTP, qACNeededtoMint, params_.recipient);\n        // All locked AC is either unlock or returned, no longer on pending Operation\n        qACLockedInPending -= params_.qACmax;\n        // transfers any AC change to the sender and distributes fees\n        _distOpResults(params_.sender, params_.sender, params_.qACmax - qACtotalNeeded, params_.vendor, feeCalcs);\n    }\n\n    /**\n     * @notice redeem Collateral Asset in exchange for Pegged Token\n     * @param params_ redeem CA function parameters\n     * @dev\n     *      i_ Pegged Token index\n     *      qTP_ amount of Pegged Token to redeem\n     *      qACmin_ minimum amount of Collateral Asset that `recipient_` expects to receive\n     *      sender_ address who sends the Pegged Token\n     *      recipient_ address who receives the Collateral Asset\n     *      vendor_ address who receives a markup. If its address(0) no markup is applied\n     * @return qACtoRedeem amount of AC sent to `recipient_`\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function _redeemTPto(\n        RedeemTPParams memory params_\n    ) internal notLiquidated notPaused returns (uint256 qACtoRedeem, FeeCalcs memory feeCalcs) {\n        uint256[] memory pACtps = _getPACtps();\n        uint256 i = _tpi(params_.tp);\n        uint256 pACtp = pACtps[i];\n        _updateTPtracking(i, pACtp);\n        // evaluates whether or not the system coverage is healthy enough to redeem TP, reverts if it's not\n        _evalCoverage(protThrld, pACtps);\n        // calculate how many total qAC are redeemed\n        // [N] = [N] * [PREC] / [PREC]\n        uint256 qACtotalToRedeem = _divPrec(params_.qTP, pACtp);\n        // if is 0 reverts because it is trying to redeem an amount below precision\n        // slither-disable-next-line incorrect-equality\n        if (qACtotalToRedeem == 0) revert QacNeededMustBeGreaterThanZero();\n        uint256 qACSurcharges;\n        (qACSurcharges, feeCalcs) = _calcFees(\n            params_.sender,\n            params_.vendor,\n            qACtotalToRedeem,\n            tpRedeemFees[params_.tp]\n        );\n        qACtoRedeem = qACtotalToRedeem - qACSurcharges;\n        if (qACtoRedeem < params_.qACmin) revert QacBelowMinimumRequired(params_.qACmin, qACtoRedeem);\n        // update flux capacitor and reverts if not allowed by accumulators\n        _updateAccumulatorsOnRedeemTP(qACtoRedeem);\n        _withdrawAndBurnTP(i, params_.qTP, qACtotalToRedeem);\n        // transfers qAC to the recipient and distributes fees\n        _distOpResults(params_.sender, params_.recipient, qACtoRedeem, params_.vendor, feeCalcs);\n    }\n\n    /**\n     * @notice mint Collateral Token and Pegged Token in exchange for Collateral Asset\n     *  This operation is done without checking coverage\n     *  Collateral Token and Pegged Token are minted in equivalent proportions so that its price\n     *  and global coverage are not modified.\n     *  Reverts if qAC sent are insufficient.\n     * @param params_ mint TC and TP function parameters\n     * @dev\n     *      i_ Pegged Token index\n     *      qTP_ amount of Pegged Token to mint\n     *      qACmax_ maximum amount of Collateral Asset that can be spent\n     *      sender_ address who sends Collateral Asset\n     *      recipient_ address who receives the Collateral Token and Pegged Token\n     *      vendor_ address who receives a markup. If its address(0) no markup is applied\n     * @return qACtoMintTC amount of AC used to mint Collateral Token\n     * @return qACtoMintTP amount of AC used to mint Pegged Token\n     * @return qACtoSpent total amount of AC spent by `sender_` for TC and TP mint plus fees\n     * @return qTCtoMint amount of Collateral Token minted\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function _mintTCandTPto(\n        MintTCandTPParams memory params_\n    )\n        internal\n        notLiquidated\n        notPaused\n        returns (\n            uint256 qACtoMintTC,\n            uint256 qACtoMintTP,\n            uint256 qACtoSpent,\n            uint256 qTCtoMint,\n            FeeCalcs memory feeCalcs\n        )\n    {\n        bytes memory payload = abi.encodeCall(MocCoreExpansion(mocCoreExpansion).mintTCandTPto, (params_));\n        (qACtoMintTC, qACtoMintTP, qACtoSpent, qTCtoMint, feeCalcs) = abi.decode(\n            Address.functionDelegateCall(mocCoreExpansion, payload),\n            (uint256, uint256, uint256, uint256, FeeCalcs)\n        );\n        // All locked AC is either unlock or returned, no longer on pending Operation\n        qACLockedInPending -= params_.qACmax;\n        // transfers any AC change to the sender and distributes fees\n        _distOpResults(params_.sender, params_.sender, params_.qACmax - qACtoSpent, params_.vendor, feeCalcs);\n    }\n\n    /**\n     * @notice redeem Collateral Asset in exchange for Collateral Token and Pegged Token\n     *  This operation is done without checking coverage\n     *  Collateral Token and Pegged Token are redeemed in equivalent proportions so that its price\n     *  and global coverage are not modified.\n     *  Reverts if qTC sent are insufficient.\n     * @param params_ redeem TC and TP function parameters\n     * @dev\n     *      i_ Pegged Token index\n     *      qTC_ maximum amount of Collateral Token to redeem\n     *      qTP_ amount of Pegged Token to redeem\n     *      qACmin_ minimum amount of Collateral Asset that `recipient_` expects to receive\n     *      sender_ address who sends Collateral Token and Pegged Token\n     *      recipient_ address who receives the Collateral Asset\n     *      vendor_ address who receives a markup. If its address(0) no markup is applied\n     * @return qACtoRedeemTC amount of AC sent to `recipient_` due to TC redemption\n     * @return qACtoRedeemTP amount of AC sent to `recipient_` due to TP redemption\n     * @return qACtoReceive total amount of AC sent to `recipient_` after fees\n     * @return qTCtoRedeem amount of Collateral Token redeemed\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function _redeemTCandTPto(\n        RedeemTCandTPParams memory params_\n    )\n        internal\n        notLiquidated\n        notPaused\n        returns (\n            uint256 qACtoRedeemTC,\n            uint256 qACtoRedeemTP,\n            uint256 qACtoReceive,\n            uint256 qTCtoRedeem,\n            FeeCalcs memory feeCalcs\n        )\n    {\n        bytes memory payload = abi.encodeCall(MocCoreExpansion(mocCoreExpansion).redeemTCandTPto, (params_));\n        (qACtoRedeemTC, qACtoRedeemTP, qACtoReceive, qTCtoRedeem, feeCalcs) = abi.decode(\n            Address.functionDelegateCall(mocCoreExpansion, payload),\n            (uint256, uint256, uint256, uint256, FeeCalcs)\n        );\n        // transfers qAC to the recipient and distributes fees\n        _distOpResults(params_.sender, params_.recipient, qACtoReceive, params_.vendor, feeCalcs);\n    }\n\n    /**\n     * @notice swap Pegged Token to another one\n     *  This operation is done without checking coverage unless the target coverage for\n     *  received Pegged Token is greater than the Pegged Token sent\n     * @param params_ swap TP for TP function parameters\n     * @dev\n     *      iFrom_ owned Pegged Token index\n     *      iTo_ target Pegged Token index\n     *      qTP_ amount of owned Pegged Token to swap\n     *      qTPmin_ minimum amount of target Pegged Token that `recipient_` expects to receive\n     *      qACmax_ maximum amount of Collateral Asset that can be spent in fees\n     *      sender_ address who sends the Pegged Token\n     *      recipient_ address who receives the target Pegged Token\n     *      vendor_ address who receives a markup. If its address(0) no markup is applied\n     * @return qTPMinted amount of Pegged Token minted\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function _swapTPforTPto(\n        SwapTPforTPParams memory params_\n    ) internal notLiquidated notPaused returns (uint256 qTPMinted, FeeCalcs memory feeCalcs) {\n        uint256 qACSurcharges;\n        bytes memory payload = abi.encodeCall(MocCoreExpansion(mocCoreExpansion).swapTPforTPto, (params_));\n        (qACSurcharges, qTPMinted, feeCalcs) = abi.decode(\n            Address.functionDelegateCall(mocCoreExpansion, payload),\n            (uint256, uint256, FeeCalcs)\n        );\n        // All locked AC is either unlock or returned, no longer on pending Operation\n        qACLockedInPending -= params_.qACmax;\n        // transfers any AC change to the sender and distributes fees\n        _distOpResults(params_.sender, params_.sender, params_.qACmax - qACSurcharges, params_.vendor, feeCalcs);\n    }\n\n    /**\n     * @notice swap Pegged Token to Collateral Token\n     * @param params_ swap TP for TC function parameters\n     * @dev\n     *      i_ Pegged Token index\n     *      qTP_ amount Pegged Token to swap\n     *      qTCmin_ minimum amount of Collateral Token that `recipient_` expects to receive\n     *      qACmax_ maximum amount of Collateral Asset that can be spent in fees\n     *      sender_ address who sends the Pegged Token\n     *      recipient_ address who receives Collateral Token\n     *      vendor_ address who receives a markup. If its address(0) no markup is applied\n     * @return qTCMinted amount of TC minted\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function _swapTPforTCto(\n        SwapTPforTCParams memory params_\n    ) internal notLiquidated notPaused returns (uint256 qTCMinted, FeeCalcs memory feeCalcs) {\n        uint256 qACSurcharges;\n        bytes memory payload = abi.encodeCall(MocCoreExpansion(mocCoreExpansion).swapTPforTCto, (params_));\n        (qACSurcharges, qTCMinted, feeCalcs) = abi.decode(\n            Address.functionDelegateCall(mocCoreExpansion, payload),\n            (uint256, uint256, FeeCalcs)\n        );\n        // All locked AC is either unlock or returned, no longer on pending Operation\n        qACLockedInPending -= params_.qACmax;\n        // transfers any AC change to the sender and distributes fees\n        _distOpResults(params_.sender, params_.sender, params_.qACmax - qACSurcharges, params_.vendor, feeCalcs);\n    }\n\n    /**\n     * @notice swap Collateral Token to Pegged Token\n     * @param params_ swap TC for TP function parameters\n     * @dev\n     *      i_ Pegged Token index\n     *      qTC_ amount of Collateral Token to swap\n     *      qTPmin_ minimum amount of Pegged Token Token that `recipient_` expects to receive\n     *      qACmax_ maximum amount of Collateral Asset that can be spent in fees\n     *      sender_ address who sends the Collateral Token\n     *      recipient_ address who receives the Pegged Token\n     *      vendor_ address who receives a markup. If its address(0) no markup is applied\n     * @return qTPtoMint amount of Pegged Token minted\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function _swapTCforTPto(\n        SwapTCforTPParams memory params_\n    ) internal notLiquidated notPaused returns (uint256 qTPtoMint, FeeCalcs memory feeCalcs) {\n        uint256 qACSurcharges;\n        bytes memory payload = abi.encodeCall(MocCoreExpansion(mocCoreExpansion).swapTCforTPto, (params_));\n        (qACSurcharges, qTPtoMint, feeCalcs) = abi.decode(\n            Address.functionDelegateCall(mocCoreExpansion, payload),\n            (uint256, uint256, FeeCalcs)\n        );\n        // All locked AC is either unlock or returned, no longer on pending Operation\n        qACLockedInPending -= params_.qACmax;\n        // transfers any AC change to the sender and distributes fees\n        _distOpResults(params_.sender, params_.sender, params_.qACmax - qACSurcharges, params_.vendor, feeCalcs);\n    }\n\n    /**\n     * @notice Allow redeem on liquidation state, user Peg balance gets burned and he receives\n     * the equivalent AC given the liquidation frozen price.\n     * @dev This function is implemented in MocCoreExpansion but with this contract context\n     * @param tp_ Pegged Token address\n     * @param sender_ address owner of the TP to be redeemed\n     * @param recipient_ address who receives the AC\n     * @return qACRedeemed amount of AC sent to `recipient_`\n     */\n    function _liqRedeemTPTo(\n        address tp_,\n        address sender_,\n        address recipient_\n    ) internal notPaused checkRecipient(sender_, recipient_) returns (uint256 qACRedeemed) {\n        bytes memory payload = abi.encodeCall(\n            MocCoreExpansion(mocCoreExpansion).liqRedeemTP,\n            (tp_, sender_, recipient_, acBalanceOf(address(this)))\n        );\n        qACRedeemed = abi.decode(Address.functionDelegateCall(mocCoreExpansion, payload), (uint256));\n        // transfer qAC to the recipient, reverts if fail\n        acTransfer(recipient_, qACRedeemed);\n        return qACRedeemed;\n    }\n\n    /**\n     * @notice Distributes Operation results to the different recipients\n     * @param sender_ address who executes the operation\n     * @param operatorsAddress_ operator's address to receive `operatorsQAC_`\n     * @param operatorsQAC_ amount of AC to transfer operator [N]\n     * @param vendor_ vendors address to pay markup to\n     * @param feeCalcs_ struct with:\n     * @dev\n     *      qACFee amount of AC needed to pay fees\n     *      qFeeToken amount of Fee Token needed to pay fess\n     *      qACVendorMarkup amount of AC needed to pay vendor markup\n     *      qFeeTokenVendorMarkup amount of Fee Token needed to pay vendor markup\n     */\n    function _distOpResults(\n        address sender_,\n        address operatorsAddress_,\n        uint256 operatorsQAC_,\n        address vendor_,\n        FeeCalcs memory feeCalcs_\n    ) internal {\n        if (feeCalcs_.qACFee > 0) {\n            // [N] = [PREC] * [N] / [PREC]\n            uint256 qACFeeRetained = _mulPrec(feeRetainer, feeCalcs_.qACFee);\n            // Increase collateral in the retain amount\n            nACcb += qACFeeRetained;\n            // transfer qAC fee to Moc Fee Flow\n            acTransfer(mocFeeFlowAddress, feeCalcs_.qACFee - qACFeeRetained);\n            // transfer qAC markup to vendor\n            acTransfer(vendor_, feeCalcs_.qACVendorMarkup);\n        }\n        // if qACFee == 0 then the fees are paid in Fee Token\n        else {\n            // transfer Fee Token to Moc Fee Flow\n            _feeTokenTransfer(sender_, mocFeeFlowAddress, feeCalcs_.qFeeToken);\n            // transfer Fee Token to vendor\n            _feeTokenTransfer(sender_, vendor_, feeCalcs_.qFeeTokenVendorMarkup);\n        }\n        // transfer qAC to operator\n        acTransfer(operatorsAddress_, operatorsQAC_);\n    }\n\n    /**\n     * @notice transfer Fee Tokens from an address to another\n     * @dev this function could revert during safeTransfer call.\n     *  safeTransfer will revert if token transfer reverts or returns 0\n     * @param from_ address who sends the Fee Token\n     * @param to_ address who receives the Fee Token\n     * @param amount_ amount of Fee Token to transfer\n     */\n    function _feeTokenTransfer(address from_, address to_, uint256 amount_) internal {\n        if (amount_ > 0) SafeERC20.safeTransferFrom(feeToken, from_, to_, amount_);\n    }\n\n    // ------- Public Functions -------\n\n    /**\n     * @notice Allow redeem on liquidation state, user Peg balance gets burned and he receives\n     * the equivalent AC given the liquidation frozen price.\n     * @param tp_ Pegged Token address\n     * @param recipient_ address who receives the AC\n     * @return qACRedeemed amount of AC sent to `recipient_`\n     */\n    function liqRedeemTP(address tp_, address recipient_) external returns (uint256 qACRedeemed) {\n        return _liqRedeemTPTo(tp_, msg.sender, recipient_);\n    }\n\n    /**\n     * @notice distribute appreciation factor to beneficiary and success fee to Moc Fee Flow\n     */\n    function _distributeSuccessFee() internal {\n        uint256 mocGain = 0;\n        uint256 pegAmount = pegContainer.length;\n        uint256[] memory tpToMint = new uint256[](pegAmount);\n        for (uint256 i = 0; i < pegAmount; i = unchecked_inc(i)) {\n            uint256 pACtp = _getPACtp(i);\n            _updateTPtracking(i, pACtp);\n            int256 iou = tpiou[i];\n            if (iou > 0) {\n                // [N] = (([PREC] * [PREC] / [PREC]) * [N]) / [PREC]\n                tpToMint[i] = _mulPrec(_mulPrec(appreciationFactor, pACtp), uint256(iou));\n                // [N] = [N] + [N]\n                mocGain += uint256(iou);\n                // reset TP profit\n                tpiou[i] = 0;\n                _depositAndMintTP(i, tpToMint[i], 0, mocAppreciationBeneficiaryAddress);\n            }\n        }\n        if (mocGain != 0) {\n            // [N] = [N] * [PREC] / [PREC]\n            mocGain = _mulPrec(mocGain, successFee);\n            // sub qAC from the Bucket\n            nACcb -= mocGain;\n            // transfer the mocGain AC to Moc Fee Flow\n            acTransfer(mocFeeFlowAddress, mocGain);\n        }\n        emit SuccessFeeDistributed(mocGain, tpToMint);\n    }\n\n    // ------- External Functions -------\n\n    /**\n     * @notice this function is executed during settlement.\n     *  stores amount of locked AC by Pegged Tokens at this moment and distribute success fee\n     */\n    function execSettlement() external notPaused {\n        // check if it is in the corresponding time to execute the settlement\n        if (block.timestamp < nextSettlementTime) revert MissingTimeToSettlement();\n        unchecked {\n            nextSettlementTime = block.timestamp + settlementTimeSpan;\n        }\n        emit SettlementExecuted();\n        _distributeSuccessFee();\n    }\n\n    /**\n     * @notice executes the interest payment of the TC holders\n     *  can only be executed after `tcInterestPaymentTimeSpan`\n     * @dev\n     *  -   The amount is not differential, it's a snapshot of the moment it's executed\n     *  -   It does not check coverage\n     */\n    function tcHoldersInterestPayment() external notPaused {\n        // check if it is in the corresponding time to execute the interest payment\n        if (block.timestamp < nextTCInterestPayment) revert MissingTimeToTCInterestPayment();\n        unchecked {\n            nextTCInterestPayment = block.timestamp + tcInterestPaymentTimeSpan;\n        }\n        // [N] = [N] * [PREC] / [PREC]\n        uint256 interestAmount = _mulPrec(nACcb, tcInterestRate);\n        emit TCInterestPayment(interestAmount);\n        // sub interests from the Bucket\n        nACcb -= interestAmount;\n        // transfer interests to the interest collector address, reverts if fail\n        acTransfer(tcInterestCollectorAddress, interestAmount);\n    }\n\n    /**\n     * @notice removes TPs from the bucket and send AC to the MultiCollateralGuard contract\n     *  called during a rebalancing process\n     * @dev only called by MultiCollateralGuard contract\n     * @param tp_ Pegged Token address\n     * @param qTP_ amount of TPs to remove\n     * @param qAC_ amount of AC to sent\n     */\n    function rebalance(address tp_, uint256 qTP_, uint256 qAC_) external onlyMultiCollateralGuard {\n        uint256 tpIndex = _tpi(tp_);\n        _updateTPtracking(tpIndex, _getPACtp(tpIndex));\n        _withdrawTP(tpIndex, qTP_, qAC_);\n        acTransfer(msg.sender, qAC_);\n    }\n\n    /**\n     * @notice adds TPs to the bucket\n     *  called during a rebalancing process\n     * @dev only called by MultiCollateralGuard contract\n     * @param tp_ Pegged Token address\n     * @param qTP_ amount of TPs to add\n     */\n    function acceptRebalance(address tp_, uint256 qTP_) external onlyMultiCollateralGuard {\n        uint256 tpIndex = _tpi(tp_);\n        _updateTPtracking(tpIndex, _getPACtp(tpIndex));\n        // qAC will be taking on account when the AC is transferred\n        _depositTP(tpIndex, qTP_, 0 /*qAC*/);\n    }\n\n    // ------- Only Authorized Changer Functions -------\n\n    /**\n     * @dev sets Moc Core Expansion contract address\n     * @param mocCoreExpansion_ moc core expansion new contract address\n     */\n    function setMocCoreExpansion(address mocCoreExpansion_) external onlyAuthorizedChanger {\n        // slither-disable-next-line missing-zero-check\n        mocCoreExpansion = mocCoreExpansion_;\n    }\n\n    /**\n     * @notice add a Pegged Token to the protocol\n     * @dev Note that the ema value, should consider `nextEmaCalculation`\n     *  This function is implemented in MocCoreExpansion but with this contract context\n     *  @param tpToken_ Pegged Token contract to add\n     *  peggedTokenParams_ params of Pegged Token to add:\n     *      priceProviderAddress Pegged Token price provider contract address\n     *      tpCtarg Pegged Token target coverage [PREC]\n     *      tpMintFee additional fee pct applied on mint [PREC]\n     *      tpRedeemFee additional fee pct applied on redeem [PREC]\n     *      tpEma initial Pegged Token exponential moving average [PREC]\n     *      tpEmaSf Pegged Token smoothing factor [PREC]\n     * @dev Pegged Token should be added using the corresponding changer template, which\n     *      should guarantee that it is added on all the buckets(mandatory for multiCollateral)\n     *\n     *  Requirements:\n     *\n     * - the caller must have governance authorization.\n     * - tpToken must be a MocRC20, with mint, burn roles already settled\n     *  for this contract\n     */\n    function addPeggedToken(\n        IMocRC20 tpToken_,\n        PeggedTokenParams calldata peggedTokenParams_\n    ) external onlyAuthorizedChanger {\n        bytes memory payload = abi.encodeCall(\n            MocCoreExpansion(mocCoreExpansion).addPeggedToken,\n            (tpToken_, peggedTokenParams_)\n        );\n        // slither-disable-next-line unused-return\n        Address.functionDelegateCall(mocCoreExpansion, payload);\n    }\n\n    /**\n     * @notice modifies a Pegged Token of the protocol\n     * @dev Note that the ema value, should consider `nextEmaCalculation`\n     *  This function is implemented in MocCoreExpansion but with this contract context\n     *  @param tpToken_ Pegged Token contract to edit\n     *  peggedTokenParams_ params of Pegged Token to edit:\n     *      priceProviderAddress Pegged Token price provider contract address\n     *      tpCtarg Pegged Token target coverage [PREC]\n     *      tpMintFee additional fee pct applied on mint [PREC]\n     *      tpRedeemFee additional fee pct applied on redeem [PREC]\n     *      tpEma initial Pegged Token exponential moving average [PREC]\n     *      tpEmaSf Pegged Token smoothing factor [PREC]\n     *\n     *  Requirements:\n     *\n     * - the caller must have governance authorization.\n     * - the tpTokenAddress must exists\n     */\n    function editPeggedToken(\n        IMocRC20 tpToken_,\n        PeggedTokenParams calldata peggedTokenParams_\n    ) external onlyAuthorizedChanger {\n        bytes memory payload = abi.encodeCall(\n            MocCoreExpansion(mocCoreExpansion).editPeggedToken,\n            (tpToken_, peggedTokenParams_)\n        );\n        // slither-disable-next-line unused-return\n        Address.functionDelegateCall(mocCoreExpansion, payload);\n    }\n\n    /**\n     * @notice liquidate the bucket, settling the TPs liquidation prices and blocking all mint & redeem operations.\n     * @dev it should only be used when it is the only bucket available\n     *  because it is a single collateral protocol or a multi collateral but the rest has already been liquidated\n     *\n     * May emit a {ContractLiquidated} event.\n     */\n    function liquidate() external notPaused onlyMultiCollateralGuard {\n        liquidated = true;\n        // Freeze current Peg Price given the AC available\n        bytes memory payload = abi.encodeCall(MocCoreExpansion(mocCoreExpansion).settleLiquidationPrices, ());\n        Address.functionDelegateCall(mocCoreExpansion, payload);\n    }\n\n    /**\n     * @notice set liquidated\n     * @dev only called by MocMultiCollateralGuard after rebalancing all the TPs to other buckets.\n     *  This bucket will be removed from the multi collateral protocol as well\n     */\n    function setLiquidated() external notPaused onlyMultiCollateralGuard {\n        liquidated = true;\n    }\n\n    /**\n     * @dev sets Moc Vendors contract address\n     * @param mocVendors_ moc Vendors new contract address\n     */\n    function setMocVendors(address mocVendors_) external onlyAuthorizedChanger {\n        // slither-disable-next-line missing-zero-check\n        mocVendors = MocVendors(mocVendors_);\n    }\n\n    // ------- Getters Functions -------\n\n    /**\n     * @notice gets Pegged Token minted\n     * @return nTP\n     */\n    function getNTP(address tp_) external view returns (uint256 nTP) {\n        return pegContainer[_tpi(tp_)].nTP;\n    }\n\n    /**\n     * @notice gets Collateral Token price\n     * @return pTCac [PREC]\n     */\n    function getPTCac() external view returns (uint256 pTCac) {\n        (uint256 lckAC, uint256 nACgain) = _getLckACandACgain(_getPACtps());\n        return _getPTCac(lckAC, nACgain);\n    }\n\n    /**\n     * @notice calc Collateral Token price given an array of TP prices\n     * @param pACtps_ All tps prices [PREC]\n     * @return pTCac [PREC]\n     */\n    function calcPTCac(uint256[] calldata pACtps_) external view returns (uint256 pTCac) {\n        (uint256 lckAC, uint256 nACgain) = _getLckACandACgain(pACtps_);\n        return _getPTCac(lckAC, nACgain);\n    }\n\n    /**\n     * @notice gets all TP prices\n     * @return pACtps All tps prices [PREC]\n     */\n    function getPACtps() external view returns (uint256[] memory pACtps) {\n        return _getPACtps();\n    }\n\n    /**\n     * @notice get the min or max last publication block among all Pegged Tokens\n     * @param useMaxLastPublicationBlock_ use the max last publication block to trigger the queue execution\n     * @return lastPublicationBlock the max last block where there was a price publication\n     */\n    function getLastPublicationBlock(\n        bool useMaxLastPublicationBlock_\n    ) external view returns (uint256 lastPublicationBlock) {\n        lastPublicationBlock = pegContainer[0].priceProvider.getLastPublicationBlock();\n        uint256 pegAmount = pegContainer.length;\n        for (uint256 i = 1; i < pegAmount; i = unchecked_inc(i)) {\n            uint256 tpLastPublicationBlock = pegContainer[i].priceProvider.getLastPublicationBlock();\n            lastPublicationBlock = useMaxLastPublicationBlock_\n                ? Math.max(lastPublicationBlock, tpLastPublicationBlock)\n                : Math.min(lastPublicationBlock, tpLastPublicationBlock);\n        }\n    }\n\n    /**\n     * @notice gets bucket global coverage\n     * @return cglob [PREC]\n     */\n    function getCglb() external view returns (uint256 cglob) {\n        (uint256 lckAC, uint256 nACgain) = _getLckACandACgain(_getPACtps());\n        return _getCglb(lckAC, nACgain);\n    }\n\n    /**\n     * @notice calc bucket global coverage given an array of TP prices\n     * @param pACtps_ All tps prices [PREC]\n     * @return cglob [PREC]\n     */\n    function calcCglb(uint256[] calldata pACtps_) external view returns (uint256 cglob) {\n        (uint256 lckAC, uint256 nACgain) = _getLckACandACgain(pACtps_);\n        return _getCglb(lckAC, nACgain);\n    }\n\n    /**\n     * @notice gets amount of Collateral Asset locked by Pegged Token\n     * @return lckAC [PREC]\n     */\n    function getLckAC() external view returns (uint256 lckAC) {\n        (lckAC, ) = _getLckACandACgain(_getPACtps());\n    }\n\n    /**\n     * @notice calc amount of Collateral Asset locked by Pegged Token given an array of TP prices\n     * @param pACtps_ All tps prices [PREC]\n     * @return lckAC [PREC]\n     */\n    function calcLckAC(uint256[] calldata pACtps_) external view returns (uint256 lckAC) {\n        (lckAC, ) = _getLckACandACgain(pACtps_);\n    }\n\n    /**\n     * @notice calc global coverage and amount of Collateral Asset locked by Pegged Token given an array of TP prices\n     * @param i_ Pegged Token index\n     * @notice gets amount of Collateral Asset locked by a given Pegged Token\n     * @return lckAC [PREC]\n     */\n    function getLckACByTP(uint256 i_) external view returns (uint256 lckAC) {\n        uint256 pACtp = _getPACtp(i_);\n        (uint256 tpGain, ) = _getPnLTP(i_, pACtp);\n        // [N] = ([N] + [N]) * [PREC] / [PREC]\n        return _divPrec(pegContainer[i_].nTP + tpGain, pACtp);\n    }\n\n    /**\n     * @notice gets global coverage and amount of Collateral Asset locked by Pegged Token\n     * @return cglob [PREC]\n     * @return lckAC [PREC]\n     */\n    function calcCglbAndLckAC(uint256[] calldata pACtps_) external view returns (uint256 cglob, uint256 lckAC) {\n        uint256 nACgain;\n        (lckAC, nACgain) = _getLckACandACgain(pACtps_);\n        return (_getCglb(lckAC, nACgain), lckAC);\n    }\n\n    /**\n     * @notice calc amount of Collateral Asset available considering how many are locked by Pegged Token adjusted by EMA\n     *  given an array of TP prices\n     * @param pACtps_ All tps prices [PREC]\n     * @return lckACemaAdjusted [PREC]\n     */\n    function calcLckACemaAdjusted(uint256[] calldata pACtps_) external view returns (int256 lckACemaAdjusted) {\n        uint256 ctargemaCA = _calcCtargemaCA(pACtps_);\n        (uint256 lckAC, uint256 nACgain) = _calcLckACandACgain(pACtps_);\n        return _getLckACemaAdjusted(ctargemaCA, lckAC, nACgain);\n    }\n\n    /**\n     * @notice gets amount of Collateral Token available to redeem signed\n     * @dev because it is a view function we are not calculating the new ema,\n     *  since we are using the last ema calculation, this may differ a little from the real amount\n     *  of TC available to redeem. Consider it an approximation.\n     * @return tcAvailableToRedeem [N]\n     */\n    function getTCAvailableToRedeem() external view returns (uint256 tcAvailableToRedeem) {\n        return calcTCAvailableToRedeem(_getPACtps());\n    }\n\n    /**\n     * @notice calc amount of Collateral Token available to redeem signed given an array of TP prices\n     * @dev because it is a view function we are not calculating the new ema,\n     *  since we are using the last ema calculation, this may differ a little from the real amount\n     *  of TC available to redeem. Consider it an approximation.\n     * @param pACtps_ All tps prices [PREC]\n     * @return tcAvailableToRedeem [N]\n     */\n    function calcTCAvailableToRedeem(uint256[] memory pACtps_) public view returns (uint256 tcAvailableToRedeem) {\n        uint256 ctargemaCA = _calcCtargemaCA(pACtps_);\n        (uint256 lckAC, uint256 nACgain) = _calcLckACandACgain(pACtps_);\n        return _getTCAvailableToRedeem(ctargemaCA, lckAC, nACgain);\n    }\n\n    /**\n     * @notice gets amount of Pegged Token available to mint signed\n     * @dev because it is a view function we are not calculating the new ema,\n     *  since we are using the last ema calculation, this may differ a little from the real amount\n     *  of TP available to mint. Consider it an approximation.\n     * @param tp_ Pegged Token address\n     * @return tpAvailableToMintSigned [N]\n     */\n    function getTPAvailableToMint(address tp_) external view returns (int256 tpAvailableToMintSigned) {\n        return calcTPAvailableToMint(tp_, _getPACtps());\n    }\n\n    /**\n     * @notice calc amount of Pegged Token available to mint signed given an array of TP prices\n     * @dev because it is a view function we are not calculating the new ema,\n     *  since we are using the last ema calculation, this may differ a little from the real amount\n     *  of TP available to mint. Consider it an approximation.\n     * @param tp_ Pegged Token address\n     * @param pACtps_ All tps prices [PREC]\n     * @return tpAvailableToMintSigned [N]\n     */\n    function calcTPAvailableToMint(\n        address tp_,\n        uint256[] memory pACtps_\n    ) public view returns (int256 tpAvailableToMintSigned) {\n        uint256 ctargemaCA = _calcCtargemaCA(pACtps_);\n        (uint256 lckAC, uint256 nACgain) = _calcLckACandACgain(pACtps_);\n        uint256 i = _tpi(tp_);\n        uint256 pACtp = pACtps_[i];\n        return _getTPAvailableToMintSigned(ctargemaCA, _getCtargemaTP(i, pACtp, protThrld), pACtp, lckAC, nACgain);\n    }\n\n    /**\n     * @notice gets total Collateral Asset available\n     * @return totalACavailable [N]\n     */\n    function getTotalACavailable() external view returns (uint256 totalACavailable) {\n        (, uint256 nACgain) = _getLckACandACgain(_getPACtps());\n        return _getTotalACavailable(nACgain);\n    }\n\n    /**\n     * @notice returns true if bucket can be liquidated\n     */\n    function isLiquidationAvailable() external view returns (bool) {\n        return liqEnabled && !liquidated && isLiquidationReached();\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/v3/TaskExecuteQueueV3.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../ITask.sol\";\nimport { MocMultiCollateralGuard } from \"@moc/moc-main/contracts/multiCollateral/MocMultiCollateralGuard.sol\";\nimport { MocOperations } from \"@moc/moc-main/contracts/core/MocOperations.sol\";\nimport { Utils } from \"../Utils.sol\";\n\n/**\n * @title TaskExecuteQueueV3\n * @notice This contract implements a task that executes the MocQueue.\n */\ncontract TaskExecuteQueueV3 is ITask {\n    error InvalidPACtpPrice();\n    error TaskNotAvailable();\n\n    MocMultiCollateralGuard public immutable mocMultiCollateralGuard;\n\n    /**\n     * @notice Constructor\n     * @param mocMultiCollateralGuard_ The address of the MocMultiCollateralGuard contract.\n     */\n    constructor(address payable mocMultiCollateralGuard_) {\n        mocMultiCollateralGuard = MocMultiCollateralGuard(mocMultiCollateralGuard_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() public view returns (bool) {\n        MocMultiCollateralGuard mocMC = mocMultiCollateralGuard;\n        if (mocMC.paused() || !_areValidAllBucketPrices(mocMC)) return false;\n        return (mocMC.readyToExecute());\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        mocMultiCollateralGuard.execute();\n    }\n\n    /**\n     * @notice returns true if all PACtps are valid\n     * @param mocMultiCollateralGuard_ The MocMultiCollateralGuard contract\n     * @dev This function checks all PACtps in all buckets to ensure their price providers\n     *  are valid.\n     */\n    function _areValidAllBucketPrices(MocMultiCollateralGuard mocMultiCollateralGuard_) internal view returns (bool) {\n        uint256 bucketsLength = mocMultiCollateralGuard_.getBucketAmount();\n        for (uint256 i = 0; i < bucketsLength; i++) {\n            MocOperations bucket = mocMultiCollateralGuard_.buckets(i);\n            bool areValidPrices = Utils._areValidPrices(address(bucket));\n            if (!areValidPrices) return false;\n        }\n        return true;\n    }\n\n    /**\n     * @notice returns true if all PACtps are valid\n     */\n    function areValidAllBucketPrices() external view returns (bool) {\n        return _areValidAllBucketPrices(mocMultiCollateralGuard);\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/token/ERC20/utils/SafeERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(IERC20 token, address spender, uint256 value) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n     * Revert on invalid signature.\n     */\n    function safePermit(\n        IERC20Permit token,\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal {\n        uint256 nonceBefore = token.nonces(owner);\n        token.permit(owner, spender, value, deadline, v, r, s);\n        uint256 nonceAfter = token.nonces(owner);\n        require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n        // and not revert is the subcall reverts.\n\n        (bool success, bytes memory returndata) = address(token).call(data);\n        return\n            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n    }\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/interfaces/IDataProvider.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\n/**\n * @title IDataProvider\n * @notice Interface for peeking the data from an oracle,\n *         compatible with Amphiraos and OMoC-Decentralized Oracles\n * @dev https://github.com/money-on-chain/Amphiraos-Oracle\n * @dev https://github.com/money-on-chain/OMoC-Decentralized-Oracle\n */\ninterface IDataProvider {\n    /**\n     * @notice returns the given `data` if `valid`\n     * @param data peeked\n     * @param valid true if the data is valid\n     */\n    function peek() external view returns (bytes32 data, bool valid);\n}\n"},{"file_path":"project/contracts/changers/preTasksRunnerChanger/PreTasksRunnerChanger.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IChangeContract } from \"moc-main-latest/contracts/interfaces/IChangeContract.sol\";\nimport { IDataProvider } from \"moc-main-latest/contracts/interfaces/IDataProvider.sol\";\n\ninterface IUpgradeDelegator {\n    function upgrade(address proxy, address newImplementation) external;\n}\n\ninterface IOracleManager {\n    function getCoinPairCount() external view returns (uint256);\n    function getCoinPairAtIndex(uint256 i) external view returns (bytes32);\n    function getContractAddress(bytes32 coinPair) external view returns (address);\n    function unregisterCoinPair(bytes32 coinPair, uint256 hint) external;\n    function registerCoinPair(bytes32 coinPair, address addr) external;\n}\n\ninterface ICoinPairPrice {\n    function addPriceQueryModeWhitelist(address _account) external;\n}\n\ninterface IMocSwapperV3MultiHop {\n    function setPath(\n        address tokenA_,\n        address tokenB_,\n        address[] memory intermediateTokens_,\n        uint24[] memory fees_,\n        IDataProvider providerSwappingAtoB_\n    ) external;\n\n    function maxAmountToSwapProviders(address tokenIn_, address tokenOut_) external view returns (IDataProvider);\n}\n\n/**\n * @title PreTasksRunnerChanger\n * @notice ChangeContract used to:\n *   1. Upgrade OracleManager and all registered CoinPairPrice proxies to new implementations\n *   2. Unregister deprecated CoinPairs at indices 1, 3 and 4 from OracleManager\n *   3. Add pauser address to the priceQueryMode whitelist on the 2 remaining CoinPairs (BTCUSD and RIFUSD)\n *   4. Register the new TasksRunner proxy as a coinpair in OracleManager\n *   5. Set the RIF <-> MoC paths on the MocSwapper, preserving its existing providers\n */\ncontract PreTasksRunnerChanger is IChangeContract {\n    address public immutable oracleManagerProxy;\n    IUpgradeDelegator public immutable upgradeDelegator;\n\n    address public immutable newOracleManagerImplementation;\n    address public immutable newCoinPairImplementation;\n\n    address public immutable pauser;\n\n    address public immutable tasksRunnerProxy;\n    bytes32 public immutable tasksRunnerName;\n\n    IMocSwapperV3MultiHop public immutable mocSwapper;\n    address public immutable rifToken;\n    address public immutable mocToken;\n\n    address[] public rifToMocIntermediateTokens;\n    uint24[] public rifToMocFees;\n    address[] public mocToRifIntermediateTokens;\n    uint24[] public mocToRifFees;\n\n    address[] public coinPairProxies;\n\n    constructor(\n        address _oracleManagerProxy,\n        IUpgradeDelegator _upgradeDelegator,\n        address _newOracleManagerImplementation,\n        address _newCoinPairImplementation,\n        address _pauser,\n        address _tasksRunnerProxy,\n        bytes32 _tasksRunnerName,\n        address _mocSwapper,\n        address _rifToken,\n        address _mocToken,\n        address[] memory _rifToMocIntermediateTokens,\n        uint24[] memory _rifToMocFees,\n        address[] memory _mocToRifIntermediateTokens,\n        uint24[] memory _mocToRifFees\n    ) {\n        oracleManagerProxy = _oracleManagerProxy;\n        upgradeDelegator = _upgradeDelegator;\n        newOracleManagerImplementation = _newOracleManagerImplementation;\n        newCoinPairImplementation = _newCoinPairImplementation;\n        pauser = _pauser;\n        tasksRunnerProxy = _tasksRunnerProxy;\n        tasksRunnerName = _tasksRunnerName;\n        mocSwapper = IMocSwapperV3MultiHop(_mocSwapper);\n        rifToken = _rifToken;\n        mocToken = _mocToken;\n        rifToMocIntermediateTokens = _rifToMocIntermediateTokens;\n        rifToMocFees = _rifToMocFees;\n        mocToRifIntermediateTokens = _mocToRifIntermediateTokens;\n        mocToRifFees = _mocToRifFees;\n\n        // Read all CoinPair proxies from OracleManager at construction time\n        IOracleManager om = IOracleManager(_oracleManagerProxy);\n        uint256 count = om.getCoinPairCount();\n        for (uint256 i = 0; i < count; i++) {\n            bytes32 coinPair = om.getCoinPairAtIndex(i);\n            address proxy = om.getContractAddress(coinPair);\n            coinPairProxies.push(proxy);\n        }\n    }\n\n    function execute() external {\n        if (address(mocSwapper) != address(0)) {\n            // Only for mainnet\n            _setMocSwapperPaths();\n        }\n        _beforeUpgrade();\n        _upgrade();\n        _afterUpgrade();\n    }\n\n    function _setMocSwapperPaths() internal {\n        IDataProvider rifToMocProvider = mocSwapper.maxAmountToSwapProviders(rifToken, mocToken);\n        IDataProvider mocToRifProvider = mocSwapper.maxAmountToSwapProviders(mocToken, rifToken);\n\n        mocSwapper.setPath(rifToken, mocToken, rifToMocIntermediateTokens, rifToMocFees, rifToMocProvider);\n        mocSwapper.setPath(mocToken, rifToken, mocToRifIntermediateTokens, mocToRifFees, mocToRifProvider);\n    }\n\n    function _beforeUpgrade() internal virtual {}\n\n    /**\n     * @notice Upgrades OracleManager and all CoinPairPrice proxies.\n     * @dev All CoinPairs are upgraded before the unregister step so that\n     *      forceCloseRound (called internally by unregisterCoinPair) succeeds\n     *      with the new implementation.\n     */\n    function _upgrade() internal virtual {\n        upgradeDelegator.upgrade(oracleManagerProxy, newOracleManagerImplementation);\n        for (uint256 i = 0; i < coinPairProxies.length; i++) {\n            upgradeDelegator.upgrade(coinPairProxies[i], newCoinPairImplementation);\n        }\n    }\n\n    /**\n     * @notice Unregisters deprecated CoinPairs from the OracleManager, adds\n     *         the pauser address to the priceQueryMode whitelist on the 2 remaining\n     *         CoinPairs (BTCUSD and RIFUSD), and registers the new TasksRunner proxy.\n     * @dev Indices are read and unregistered in descending order (4, 3, 1) to avoid\n     *      index shifting caused by the internal array compaction after each removal.\n     */\n    function _afterUpgrade() internal virtual {\n        IOracleManager om = IOracleManager(oracleManagerProxy);\n\n        // Read all target coinpairs before any removal to avoid index drift\n        bytes32 cp4 = om.getCoinPairAtIndex(4); // USDCO\n        bytes32 cp3 = om.getCoinPairAtIndex(3); // USDARS\n        bytes32 cp1 = om.getCoinPairAtIndex(1); // RIFBTC\n\n        // Unregister in descending index order\n        om.unregisterCoinPair(cp4, 4); // USDCO\n        om.unregisterCoinPair(cp3, 3); // USDARS\n        om.unregisterCoinPair(cp1, 1); // RIFBTC\n\n        // Add pauser to the priceQueryMode whitelist on the 2 remaining CoinPairs\n        uint256 remainingCount = om.getCoinPairCount();\n        for (uint256 i = 0; i < remainingCount; i++) {\n            bytes32 coinPair = om.getCoinPairAtIndex(i);\n            address proxy = om.getContractAddress(coinPair);\n            ICoinPairPrice(proxy).addPriceQueryModeWhitelist(pauser);\n        }\n\n        // Register the new TasksRunner proxy as a coinpair in OracleManager\n        om.registerCoinPair(tasksRunnerName, tasksRunnerProxy);\n    }\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/oracles/TaskDistributeSupporters.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../ITask.sol\";\n\n/**\n * @title TaskDistributeSupporters\n * @notice This contract implements a task that distributes earnings to supporters.\n */\ncontract TaskDistributeSupporters is ITask {\n    ISupporters public immutable supporters;\n\n    /**\n     * @notice Constructor\n     * @param supporters_ The address of the Supporters contract.\n     */\n    constructor(address supporters_) {\n        supporters = ISupporters(supporters_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() external view returns (bool) {\n        return (supporters.isReadyToDistribute());\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        supporters.distribute();\n    }\n}\n\ninterface ISupporters {\n    /**\n      @notice Deposit earnings that will be credited to supporters.\n      @dev Earnings will be credited periodically through several blocks.\n    */\n    function distribute() external;\n\n    /**\n      @notice Return true if is ready to do a distribute call\n\n      @return true if ready\n    */\n    function isReadyToDistribute() external view returns (bool);\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/token/ERC20/ERC20Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n        __ERC20_init_unchained(name_, symbol_);\n    }\n\n    function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[45] private __gap;\n}\n"},{"file_path":"npm/price-oracle-interfaces@0.1.0/contracts/interfaces/IPriceProvider.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.7.6;\n\n/**\n * @title IPriceProvider\n * @notice Interface for peeking the price and last publication block of a given asset\n * @dev https://github.com/money-on-chain/OMoC-Decentralized-Oracle\n */\ninterface IPriceProvider {\n  /**\n   * @notice returns the given `price` for the asset if `valid`\n   * @return price assetPrice\n   * @return valid true if the price is valid\n   */\n  function peek() external view returns (bytes32 price, bool valid);\n\n  /**\n   * @notice returns the last publication block of an asset price\n   * @dev only valid for decentralized oracles\n   * @return lastPublicationBlock\n   */\n  function getLastPublicationBlock() external view returns (uint256 lastPublicationBlock);\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/access/AccessControlEnumerableUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n    function __AccessControlEnumerable_init() internal onlyInitializing {\n    }\n\n    function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n    }\n    using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n    mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns one of the accounts that have `role`. `index` must be a\n     * value between 0 and {getRoleMemberCount}, non-inclusive.\n     *\n     * Role bearers are not sorted in any particular way, and their ordering may\n     * change at any point.\n     *\n     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n     * you perform all queries on the same block. See the following\n     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n     * for more information.\n     */\n    function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n        return _roleMembers[role].at(index);\n    }\n\n    /**\n     * @dev Returns the number of accounts that have `role`. Can be used\n     * together with {getRoleMember} to enumerate all bearers of a role.\n     */\n    function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n        return _roleMembers[role].length();\n    }\n\n    /**\n     * @dev Overload {_grantRole} to track enumerable memberships\n     */\n    function _grantRole(bytes32 role, address account) internal virtual override {\n        super._grantRole(role, account);\n        _roleMembers[role].add(account);\n    }\n\n    /**\n     * @dev Overload {_revokeRole} to track enumerable memberships\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual override {\n        super._revokeRole(role, account);\n        _roleMembers[role].remove(account);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/access/IAccessControlUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     *\n     * _Available since v3.1._\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {AccessControl-_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     */\n    function renounceRole(bytes32 role, address account) external;\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/utils/ContextUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"},{"file_path":"project/contracts/providers/FCMaxAbsoluteOpProvider.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { IDataProvider } from \"moc-main-latest/contracts/interfaces/IDataProvider.sol\";\n\n/**\n * @title Flux Capacitor Operation Absolute Maximum DataProvider\n * @notice Allows the Owner, to set the value so that the protocol cold peek it.\n */\ncontract FCMaxAbsoluteOpProvider is Ownable, IDataProvider {\n    bytes32 public data;\n\n    event DataUpdated(uint256 newData);\n\n    constructor(address owner_, uint256 initialData_) Ownable() {\n        _transferOwnership(owner_);\n        data = bytes32(initialData_);\n    }\n\n    function peek() external view returns (bytes32, bool) {\n        return (data, true);\n    }\n\n    function setMaxAbsoluteOperation(uint256 data_) external onlyOwner {\n        data = bytes32(data_);\n        emit DataUpdated(data_);\n    }\n}\n"},{"file_path":"project/contracts/token/USDRIF/Governed.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport \"moc-main-latest/contracts/interfaces/IGovernor.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n  @title Governed\n  @notice Base contract to be inherited by governed contracts\n  @dev This contract is not usable on its own since it does not have any _productive useful_ behavior\n  The only purpose of this contract is to define some useful modifiers and functions to be used on the\n  governance aspect of the child contract\n  */\nabstract contract Governed is Initializable {\n    /**\n    @notice The address of the contract which governs this one\n   */\n    IGovernor public governor;\n\n    error NotAuthorizedChanger();\n\n    /**\n    @notice Modifier that protects the function\n    @dev You should use this modifier in any function that should be called through\n    the governance system\n   */\n    modifier onlyAuthorizedChanger() {\n        checkIfAuthorizedChanger();\n        _;\n    }\n\n    /**\n    @notice Initialize the contract with the basic settings\n    @dev This initialize replaces the constructor but it is not called automatically.\n    It is necessary because of the upgradeability of the contracts\n    @param governorAddress_ Governor address\n   */\n    function __Governed_init(address governorAddress_) internal onlyInitializing {\n        __Governed_init_unchained(governorAddress_);\n    }\n\n    function __Governed_init_unchained(address governorAddress_) internal onlyInitializing {\n        governor = IGovernor(governorAddress_);\n    }\n\n    /**\n    @notice Change the contract's governor. Should be called through the old governance system\n    @param newGovernor_ New governor address\n   */\n    function changeGovernor(IGovernor newGovernor_) external onlyAuthorizedChanger {\n        governor = newGovernor_;\n    }\n\n    /**\n    @notice Checks if the msg sender is an authorized changer, reverts otherwise\n   */\n    function checkIfAuthorizedChanger() internal view {\n        if (!governor.isAuthorizedChanger(msg.sender)) revert NotAuthorizedChanger();\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/mocFlow/coiner/TaskMintStep.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../../ITask.sol\";\n\ncontract TaskMintStep is ITask {\n    ICoiner public immutable coiner;\n\n    /**\n     * @notice Constructor\n     * @param coiner_ The address of the coiner contract.\n     */\n    constructor(address coiner_) {\n        coiner = ICoiner(coiner_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() external view returns (bool) {\n        return coiner.readyToMint();\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        coiner.mintStep();\n    }\n}\n\ninterface ICoiner {\n    function readyToMint() external view returns (bool);\n    function mintStep() external;\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/utils/math/SignedMathUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMathUpgradeable {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\n        }\n    }\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/mocFlow/buffer/TaskFlush.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../../ITask.sol\";\n\ncontract TaskFlush is ITask {\n    error TaskNotAvailable();\n\n    IBuffer public immutable buffer;\n\n    /**\n     * @notice Constructor\n     * @param buffer_ The address of the buffer contract.\n     */\n    constructor(address buffer_) {\n        buffer = IBuffer(buffer_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() external view returns (bool) {\n        return (_flushAvailable(buffer) != type(uint256).max);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        uint256 outputIndex = _flushAvailable(buffer);\n        if (outputIndex == type(uint256).max) revert TaskNotAvailable();\n        buffer.flush(outputIndex);\n    }\n\n    /**\n     * @dev Checks if there is a output that can run the flush task\n     * @param buffer_ The Buffer contract\n     * @return outputIndex The output index that can run the task, max uint256 if none are available\n     */\n    function _flushAvailable(IBuffer buffer_) internal view returns (uint256 outputIndex) {\n        uint256 outputsLength = buffer_.getNumOutputs();\n\n        // Check if there are any output that can run the task\n        for (uint256 i = 0; i < outputsLength; i++) {\n            if (buffer_.isFlushable(i)) {\n                return i;\n            }\n        }\n        return type(uint256).max; // Return max uint256 if no flushable output found\n    }\n\n    /**\n     * @dev Checks if there is a output that can run the flush task\n     * @return outputIndex The output index that can run the task, max uint256 if none are available\n     */\n    function flushAvailable() external view returns (uint256 outputIndex) {\n        return _flushAvailable(buffer);\n    }\n}\n\ninterface IBuffer {\n    function getNumOutputs() external view returns (uint256);\n    function isFlushable(uint256 i) external view returns (bool);\n    function flush(uint256 i) external;\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/governance/MocUpgradable.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { Stoppable } from \"../governance/Stoppable.sol\";\nimport { UUPSUpgradeable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\n// Import to allow compilation and deploy of ERC1967Proxy\n// solhint-disable-next-line no-unused-import\nimport { ERC1967Proxy } from \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\nabstract contract MocUpgradable is UUPSUpgradeable, Stoppable {\n    /**\n    @notice Modifier that protects the function\n    @dev You should use this modifier in any function that should be called through\n    the governance system or the pauser address\n   */\n    modifier onlyAuthorizedChangerOrPauser() {\n        if (!governor.isAuthorizedChanger(msg.sender) && msg.sender != pauser) revert NotAuthorizedChanger();\n        _;\n    }\n\n    // ------- Initializer -------\n    /**\n     * @notice contract initializer\n     * @param governorAddress_ The address that will define when a change contract is authorized\n     * @param pauserAddress_ The address that is authorized to pause this contract\n     */\n    function __MocUpgradable_init(address governorAddress_, address pauserAddress_) internal onlyInitializing {\n        __UUPSUpgradeable_init();\n        __Governed_init(governorAddress_);\n        __Stoppable_init_unchained(pauserAddress_, true);\n    }\n\n    /**\n     * @inheritdoc UUPSUpgradeable\n     * @dev checks that the changer that will do the upgrade is currently authorized by governance to makes\n     * changes within the system\n     * @param newImplementation new implementation contract address(not used)\n     */\n    function _authorizeUpgrade(address newImplementation) internal override onlyAuthorizedChanger {}\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/mocFlow/reverseAuction/TaskTriggerOrder.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../../ITask.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\ncontract TaskTriggerOrder is ITask, Ownable {\n    error TaskNotAvailable();\n\n    IReverseAuction public immutable reverseAuction;\n    uint256 public revertSleepTime;\n    uint256 public lastRevertTimestamp;\n\n    event TriggerOrdersReverted(string reason, bytes data);\n\n    /**\n     * @notice Constructor\n     * @param reverseAuction_ The address of the reverse auction contract.\n     * @param revertSleepTime_ The delay in seconds applied after a revert.\n     * @param owner_ The address allowed to update revertSleepTime.\n     */\n    constructor(address reverseAuction_, uint256 revertSleepTime_, address owner_) Ownable() {\n        reverseAuction = IReverseAuction(reverseAuction_);\n        revertSleepTime = revertSleepTime_;\n        _transferOwnership(owner_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() public view returns (bool) {\n        bool backoffComplete = lastRevertTimestamp == 0 || block.timestamp >= lastRevertTimestamp + revertSleepTime;\n        return backoffComplete && reverseAuction.readyToTriggerOrders();\n    }\n\n    function setRevertSleepTime(uint256 revertSleepTime_) external onlyOwner {\n        revertSleepTime = revertSleepTime_;\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        try reverseAuction.triggerOrders() {} catch Error(string memory reason) {\n            lastRevertTimestamp = block.timestamp;\n            emit TriggerOrdersReverted(reason, \"\");\n        } catch (bytes memory data) {\n            lastRevertTimestamp = block.timestamp;\n            emit TriggerOrdersReverted(\"\", data);\n        }\n    }\n}\n\ninterface IReverseAuction {\n    function readyToTriggerOrders() external view returns (bool);\n    function triggerOrders() external;\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/access/AccessControlUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n    function __AccessControl_init() internal onlyInitializing {\n    }\n\n    function __AccessControl_init_unchained() internal onlyInitializing {\n    }\n    struct RoleData {\n        mapping(address => bool) members;\n        bytes32 adminRole;\n    }\n\n    mapping(bytes32 => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with a standardized message including the required role.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     *\n     * _Available since v4.1._\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n        return _roles[role].members[account];\n    }\n\n    /**\n     * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n     * Overriding this function changes the behavior of the {onlyRole} modifier.\n     *\n     * Format of the revert message is described in {_checkRole}.\n     *\n     * _Available since v4.6._\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Revert with a standard message if `account` is missing `role`.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert(\n                string(\n                    abi.encodePacked(\n                        \"AccessControl: account \",\n                        StringsUpgradeable.toHexString(account),\n                        \" is missing role \",\n                        StringsUpgradeable.toHexString(uint256(role), 32)\n                    )\n                )\n            );\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address account) public virtual override {\n        require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event. Note that unlike {grantRole}, this function doesn't perform any\n     * checks on the calling account.\n     *\n     * May emit a {RoleGranted} event.\n     *\n     * [WARNING]\n     * ====\n     * This function should only be called from the constructor when setting\n     * up the initial roles for the system.\n     *\n     * Using this function in any other way is effectively circumventing the admin\n     * system imposed by {AccessControl}.\n     * ====\n     *\n     * NOTE: This function is deprecated in favor of {_grantRole}.\n     */\n    function _setupRole(bytes32 role, address account) internal virtual {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        _roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual {\n        if (!hasRole(role, account)) {\n            _roles[role].members[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n        }\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual {\n        if (hasRole(role, account)) {\n            _roles[role].members[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n        }\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/tokens/MocRC20.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IMocRC20 } from \"../interfaces/IMocRC20.sol\";\nimport { IGovernor, Governed } from \"../governance/Governed.sol\";\n/* solhint-disable-next-line max-line-length */\nimport { AccessControlEnumerableUpgradeable, AccessControlUpgradeable, IAccessControlUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport { ERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\nimport { UUPSUpgradeable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\n\n/**\n * @title MocRC20\n * @notice Base Moc ERC20 Token: burn, mint. It can be both Pegs and Collateral Tokens.\n * @dev ERC20 like token that allows roles allowed contracts to mint and burn (destroyed) any token.\n */\ncontract MocRC20 is IMocRC20, AccessControlEnumerableUpgradeable, ERC20Upgradeable, UUPSUpgradeable, Governed {\n    bytes32 private constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n    bytes32 private constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n    // ------- Custom Errors -------\n    error NotUniqueRole(bytes32 role);\n    error NotYourself();\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    /**\n     * @notice contract initializer\n     * @dev grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `BURNER_ROLE` to `admin_` address.\n     * @param name_ RC20 token name\n     * @param symbol_ RC20 token symbol\n     * @param admin_ address of the admin\n     * @param governor_ address of the governor\n     */\n    function initialize(\n        string memory name_,\n        string memory symbol_,\n        address admin_,\n        IGovernor governor_\n    ) external initializer {\n        __MocRC20_init(name_, symbol_, admin_, governor_);\n    }\n\n    /**\n     * @notice contract initializer\n     * @dev grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `BURNER_ROLE` to `admin_` address.\n     * @param name_ RC20 token name\n     * @param symbol_ RC20 token symbol\n     * @param admin_ address of the admin\n     * @param governor_ address of the governor\n     */\n    function __MocRC20_init(\n        string memory name_,\n        string memory symbol_,\n        address admin_,\n        IGovernor governor_\n    ) internal onlyInitializing {\n        __ERC20_init(name_, symbol_);\n        __AccessControlEnumerable_init();\n        __UUPSUpgradeable_init();\n        __Governed_init(address(governor_));\n        _grantRole(DEFAULT_ADMIN_ROLE, admin_);\n        _grantRole(MINTER_ROLE, admin_);\n        _grantRole(BURNER_ROLE, admin_);\n    }\n\n    /**\n     * @inheritdoc UUPSUpgradeable\n     * @dev checks that the changer that will do the upgrade is currently authorized by governance to makes\n     * changes within the system\n     * @param newImplementation new implementation contract address(not used)\n     */\n    function _authorizeUpgrade(address newImplementation) internal override onlyAuthorizedChanger {}\n\n    /**\n     * @dev Creates `amount` new tokens for `to`.\n     * See {ERC20-_mint}.\n     *\n     * Requirements:\n     *\n     * - the caller must have the `MINTER_ROLE`.\n     */\n    function mint(address to, uint256 amount) external virtual onlyRole(MINTER_ROLE) returns (bool) {\n        _mint(to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Burns a specific `amount` of tokens for `to`.\n     * * See {ERC20-_burn}.\n     * Requirements:\n     *\n     * - the caller must have the `BURNER_ROLE`.\n     */\n    function burn(address to, uint256 amount) external virtual onlyRole(BURNER_ROLE) {\n        _burn(to, amount);\n    }\n\n    /**\n     * @dev Grants all `roles` to `account` while sender renounces to all ``role``\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     * - no one else must have any other role\n     *\n     * May emit a {RoleGranted x3, RoleRevoked x3} event.\n     */\n    function transferAllRoles(address account) public virtual onlyRole(getRoleAdmin(DEFAULT_ADMIN_ROLE)) {\n        if (account == msg.sender) revert NotYourself();\n        // One the new admin account has roles\n        if (getRoleMemberCount(DEFAULT_ADMIN_ROLE) != 1) revert NotUniqueRole(DEFAULT_ADMIN_ROLE);\n        if (getRoleMemberCount(MINTER_ROLE) != 1) revert NotUniqueRole(MINTER_ROLE);\n        if (getRoleMemberCount(BURNER_ROLE) != 1) revert NotUniqueRole(BURNER_ROLE);\n        _grantRole(DEFAULT_ADMIN_ROLE, account);\n        _grantRole(MINTER_ROLE, account);\n        _grantRole(BURNER_ROLE, account);\n        _revokeRole(MINTER_ROLE, msg.sender);\n        _revokeRole(BURNER_ROLE, msg.sender);\n        _revokeRole(DEFAULT_ADMIN_ROLE, msg.sender);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role  OR\n     *   the caller must have be an authorized Governance changer.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(\n        bytes32 role,\n        address account\n    ) public virtual override(AccessControlUpgradeable, IAccessControlUpgradeable) {\n        _verifyRoleManagementPrivilege(role);\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role  OR\n     *   the caller must have be an authorized Governance changer.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(\n        bytes32 role,\n        address account\n    ) public virtual override(AccessControlUpgradeable, IAccessControlUpgradeable) {\n        _verifyRoleManagementPrivilege(role);\n        _revokeRole(role, account);\n    }\n\n    // ------- Internal Functions -------\n\n    function _verifyRoleManagementPrivilege(bytes32 role) internal view {\n        if (!governor.isAuthorizedChanger(msg.sender) && !hasRole(getRoleAdmin(role), msg.sender))\n            revert NotAuthorizedChanger();\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/multiCollateral/MocRebalancer.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocMultiCollateralBase, BucketParams, MocOperations, IMocSwapper } from \"./MocMultiCollateralBase.sol\";\nimport { IPriceProvider } from \"../interfaces/IPriceProvider.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/**\n * @title MocRebalancer\n * @notice It provides the methods to articulate the rebalance of AC and TP between buckets\n * It is used for:\n *  - micro liquidations: when a bucket coverage goes below the micro liquidation threshold and\n *   a certain amount of TP must be rebalanced to another bucket, the one with the best score\n *  - liquidation: when a bucket coverage goes below the liquidation threshold and\n *   all its TPs must be rebalanced to another bucket\n *  Both process can be limited by a max amount of AC allowed to swap and the target bucket capacity to\n *  receive the tokens. If there is one of those limits, it should be executed continuously in successive txs until the\n *  necessary amount of TPs were rebalanced.\n *  In a liquidation case, that could mean, remove all the buckets TPs and be full liquidated. After that\n *  the bucket will be removed from the MultiCollateral system\n *\n */\nabstract contract MocRebalancer is MocMultiCollateralBase {\n    address private constant COINBASE = address(0);\n    // ------- Custom Errors -------\n    error MissingProviderPrice(address priceProviderAddress_);\n    error MicroLiquidationNotAvailable();\n    error LiquidationNotAvailable();\n    error NoTargetBucketAvailableToRebalance();\n    error BucketNotLiquidated();\n    error CoinbaseRebalanceTransferFailed();\n\n    // ------- Events -------\n    event MicroLiquidationExecuted(\n        address executor_,\n        address indexed originBucket,\n        address indexed targetBucket_,\n        address indexed targetTP_,\n        uint256 qACtoSwap_,\n        uint256 qACOut_,\n        uint256 qTPtoRebalance_,\n        uint256 qACExecFee_\n    );\n    event PartialLiquidationExecuted(\n        address executor_,\n        address indexed originBucket,\n        address indexed targetBucket_,\n        address indexed targetTP_,\n        uint256 qACtoSwap_,\n        uint256 qACOut_,\n        uint256 qTPtoRebalance_,\n        uint256 qACExecFee_\n    );\n    event BucketLiquidated(address indexed originBucket);\n    event CoinbasePaymentFailed(uint256 amount_, address recipient_);\n\n    // ------- Storage Rebalance -------\n    // bucket AC to coinbase price provider. Not used for coinbase bucket\n    mapping(MocOperations bucket => IPriceProvider acCoinbasePriceProvider) public acCoinbasePriceProvider;\n    // bucket rebalance execution fee recipient. Not used for coinbase bucket\n    mapping(MocOperations bucket => address rebalanceExecFeeRecipient) public rebalanceExecFeeRecipient;\n    // MocSwapper contracts for the originBucketAC / targetBucketAC pool\n    mapping(MocOperations originBucket => mapping(MocOperations targetBucket => IMocSwapper mocSwapper))\n        public mocSwappers;\n\n    // ------- Storage MicroLiquidation -------\n    // coinbase micro liquidation execution fee. Paid from the rebalanced bucket to the executor\n    uint256 public microLiquidationExecCost;\n    // target coverage to reach during a micro liquidation [PREC]\n    mapping(MocOperations bucket => uint256 rtcThrld) public rtcThrld;\n    // threshold to trigger the micro liquidation [PREC]\n    mapping(MocOperations bucket => uint256 microLiquidationThrld) public microLiquidationThrld;\n    // additional pct of AC sent to the target bucket during a micro liquidation [PREC]\n    mapping(MocOperations bucket => uint256 penaltyRate) public penaltyRate;\n\n    // ------- Storage Liquidation -------\n    // coinbase liquidation execution fee. Paid from the liquidated bucket to the executor\n    uint256 public liquidationExecCost;\n\n    // ------- Storage Execution Fees -------\n    // address who receives all the coinbase execution fees(queue and coinbase bucket rebalancing executions)\n    address payable public coinbaseExecFeeRecipient;\n\n    // ------- Initializer -------\n    /**\n     * @notice contract initializer\n     * @param microLiquidationExecCost_ coinbase micro liquidation execution fee. Paid from the\n     *  rebalanced bucket to the executor\n     * @param liquidationExecCost_ coinbase liquidation execution fee. Paid from the liquidated bucket to the executor\n     * @param coinbaseExecFeeRecipient_ address who receives all the coinbase execution fees\n     */\n    function __MocRebalancer_init(\n        uint256 microLiquidationExecCost_,\n        uint256 liquidationExecCost_,\n        address payable coinbaseExecFeeRecipient_\n    ) internal onlyInitializing {\n        microLiquidationExecCost = microLiquidationExecCost_;\n        liquidationExecCost = liquidationExecCost_;\n        coinbaseExecFeeRecipient = coinbaseExecFeeRecipient_;\n    }\n\n    // ------- Internal Functions -------\n    /**\n     * @inheritdoc MocMultiCollateralBase\n     */\n    function _setRebalanceParams(\n        MocOperations bucket_,\n        BucketParams calldata params_,\n        IMocSwapper[] memory mocSwappers_\n    ) internal override {\n        // bucket AC to coinbase price provider\n        acCoinbasePriceProvider[bucket_] = IPriceProvider(params_.acCoinbasePriceProvider);\n        rebalanceExecFeeRecipient[bucket_] = params_.rebalanceExecFeeRecipient;\n        // target coverage to reach during a micro liquidation [PREC]\n        rtcThrld[bucket_] = params_.rtcThrld;\n        // threshold to trigger the micro liquidation [PREC]\n        microLiquidationThrld[bucket_] = params_.microLiquidationThrld;\n        // additional pct of AC sent to the target bucket during a micro liquidation [PREC]\n        penaltyRate[bucket_] = params_.penaltyRate;\n        // fill the map with the MocSwapper contracts for each bucket\n        for (uint256 j = 0; j < mocSwappers_.length; j = unchecked_inc(j)) {\n            mocSwappers[buckets[j]][bucket_] = mocSwappers_[j];\n            mocSwappers[bucket_][buckets[j]] = mocSwappers_[j];\n        }\n    }\n\n    /**\n     * @notice transfers the amount of coinbase specified to the recipient\n     * @dev emit CoinbasePaymentFailed if the transfer fails\n     * @param amount_ amount of coinbase to transfer\n     * @param recipient_ address of the recipient\n     */\n    function _coinbaseTransfer(uint256 amount_, address recipient_) internal {\n        if (amount_ > 0) {\n            // solhint-disable-next-line avoid-low-level-calls\n            (bool success, ) = recipient_.call{ value: amount_ }(\"\");\n            // transfer failures are expected to be exceptional. In such cases, an event is emitted\n            // and the funds remain in the contract, to be recovered later through governance.\n            if (!success) emit CoinbasePaymentFailed(amount_, recipient_);\n        }\n    }\n\n    /**\n     * @notice calculates target bucket to receive micro liquidation given a `originBucket_` and the buckets array\n     * @param originBucket_ origin bucket to rebalance\n     * @param buckets_ buckets array\n     * @return targetBucket target bucket to receive micro liquidation\n     * @return targetBucketCglb target bucket coverage [PREC]\n     */\n    function _calcTargetBucketToRebalanceOnMicroLiquidation(\n        MocOperations originBucket_,\n        MocOperations[] memory buckets_\n    ) internal view returns (MocOperations targetBucket, uint256 targetBucketCglb) {\n        uint256 maxScore;\n        for (uint256 j = 0; j < buckets_.length; j = unchecked_inc(j)) {\n            MocOperations currBucket = buckets_[j];\n            if (currBucket != originBucket_) {\n                uint256 bucketCglb = currBucket.getCglb();\n                // empty buckets are not eligible to receive micro liquidations, so they are filtered out\n                if (bucketCglb > rtcThrld[currBucket] && bucketCglb < UINT256_MAX) {\n                    // [PREC] = [PREC] * [N] / [PREC]\n                    uint256 bucketScore = (bucketCglb * currBucket.getTotalACavailable()) / currBucket.getCtargemaCA();\n                    if (bucketScore > maxScore) {\n                        maxScore = bucketScore;\n                        targetBucket = currBucket;\n                        targetBucketCglb = bucketCglb;\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * @notice calculates target bucket to receive liquidation given a `originBucket_` and the buckets array\n     * @param originBucket_ origin bucket to rebalance\n     * @param buckets_ buckets array\n     * @return targetBucket target bucket to receive liquidation\n     * @return targetBucketCglb target bucket coverage [PREC]\n     * @return thrld threshold to limit the amount of TP available to mint on target bucket\n     */\n    function _calcTargetBucketToRebalanceOnLiquidation(\n        MocOperations originBucket_,\n        MocOperations[] memory buckets_\n    ) internal view returns (MocOperations targetBucket, uint256 targetBucketCglb, uint256 thrld) {\n        // Temporary arrays to store by matching Cglb criteria [rtcThrld, liqThrld, 0] respectively\n        uint256[] memory maxScore = new uint256[](3);\n        MocOperations[] memory targets = new MocOperations[](3);\n        uint256[] memory targetBucketCglbs = new uint256[](3);\n        uint256[] memory thrlds = new uint256[](3);\n\n        for (uint256 j = 0; j < buckets_.length; j = unchecked_inc(j)) {\n            MocOperations currBucket = buckets_[j];\n            if (currBucket != originBucket_) {\n                uint256 liqThrld = currBucket.liqThrld();\n                uint256 bucketCglb = currBucket.getCglb();\n                // empty buckets are not eligible to receive liquidations, so they are filtered out\n                if (bucketCglb < UINT256_MAX) {\n                    // [PREC] = [PREC] * [N] / [PREC]\n                    uint256 bucketScore = (bucketCglb * currBucket.getTotalACavailable()) / currBucket.getCtargemaCA();\n                    if (bucketScore > maxScore[2]) {\n                        maxScore[2] = bucketScore;\n                        targets[2] = currBucket;\n                        targetBucketCglbs[2] = bucketCglb;\n                        thrlds[2] = 0;\n                    }\n                    if (bucketCglb > liqThrld) {\n                        if (bucketScore > maxScore[1]) {\n                            maxScore[1] = bucketScore;\n                            targets[1] = currBucket;\n                            targetBucketCglbs[1] = bucketCglb;\n                            thrlds[1] = liqThrld;\n                        }\n                        uint256 bucketRTCThrld = rtcThrld[currBucket];\n                        if (bucketCglb > bucketRTCThrld && bucketScore > maxScore[0]) {\n                            maxScore[0] = bucketScore;\n                            targets[0] = currBucket;\n                            targetBucketCglbs[0] = bucketCglb;\n                            thrlds[0] = bucketRTCThrld;\n                        }\n                    }\n                }\n            }\n        }\n        // If there is any over the rtcThrld, we return that one\n        if (address(targets[0]) != address(0)) return (targets[0], targetBucketCglbs[0], thrlds[0]);\n        // Else, if there is any over the liqThrld\n        if (address(targets[1]) != address(0)) return (targets[1], targetBucketCglbs[1], thrlds[1]);\n        // Else, we return the best ranked\n        return (targets[2], targetBucketCglbs[2], thrlds[2]);\n    }\n\n    /**\n     * @notice calculates target bucket to receive micro liquidation given a `originBucket_` and the buckets array\n     * @param originBucket_ origin bucket to rebalance\n     * @return targetBucket target bucket to receive micro liquidation\n     * @return targetBucketCglb target bucket coverage [PREC]\n     */\n    function _getTargetBucketToRebalanceOnMicroLiquidation(\n        MocOperations originBucket_\n    ) internal returns (MocOperations targetBucket, uint256 targetBucketCglb) {\n        MocOperations[] memory bucketsArray = buckets;\n        _updatesCtargemaCA(bucketsArray);\n        return _calcTargetBucketToRebalanceOnMicroLiquidation(originBucket_, bucketsArray);\n    }\n\n    /**\n     * @notice calculates target bucket to receive liquidation given a `originBucket_` and the buckets array\n     * @param originBucket_ origin bucket to rebalance\n     * @return targetBucket target bucket to receive liquidation\n     * @return targetBucketCglb target bucket coverage [PREC]\n     * @return thrld threshold to limit the amount of TP available to mint on target bucket\n     */\n    function _getTargetBucketToRebalanceOnLiquidation(\n        MocOperations originBucket_\n    ) internal returns (MocOperations targetBucket, uint256 targetBucketCglb, uint256 thrld) {\n        MocOperations[] memory bucketsArray = buckets;\n        _updatesCtargemaCA(bucketsArray);\n        return _calcTargetBucketToRebalanceOnLiquidation(originBucket_, bucketsArray);\n    }\n\n    /**\n     * @notice gets target TP to rebalance given a `originBucket_`\n     * @param originBucket_ origin bucket to rebalance\n     * @return targetTP target TP to rebalance\n     */\n    function _getTPMostLockedAC(MocOperations originBucket_) internal view returns (address) {\n        uint256 tpAmount = originBucket_.getTpAmount();\n        if (tpAmount == 1) return address(originBucket_.tpTokens(0));\n\n        uint256 maxLckAC;\n        uint256 iTPMaxLckAC;\n        for (uint256 i = 0; i < tpAmount; i = unchecked_inc(i)) {\n            uint256 lckAC = originBucket_.getLckACByTP(i);\n            if (lckAC > maxLckAC) {\n                maxLckAC = lckAC;\n                iTPMaxLckAC = i;\n            }\n        }\n        return address(originBucket_.tpTokens(iTPMaxLckAC));\n    }\n\n    /**\n     * @notice calculates TP available to mint for a `targetBucket_` and a `targetTP_`\n     * @param targetBucket_ target bucket to rebalance\n     * @param targetBucketCglb_ target bucket coverage [PREC]\n     * @param targetBucketPACtp_ pACtp of the target TP for the target bucket\n     * @param thrld_ threshold to limit the amount of TP available to mint on target bucket\n     * @return tpAvailable amount of TP available on target bucket\n     *\n     */\n    function _calcTPAvailableTargetBucket(\n        MocOperations targetBucket_,\n        uint256 targetBucketCglb_,\n        uint256 targetBucketPACtp_,\n        uint256 thrld_\n    ) internal view returns (uint256) {\n        if (thrld_ <= ONE) return UINT256_MAX;\n        // [PREC²] = ([PREC] - [PREC]) * [N]) * [PREC]\n        uint256 num = (targetBucketCglb_ - thrld_) * targetBucket_.getTotalACavailable() * targetBucketPACtp_;\n        // [PREC²] = [PREC] * ([PREC] - [PREC])\n        uint256 den = targetBucketCglb_ * (thrld_ - ONE);\n        // [N] = [PREC²] / [PREC²]\n        return num / den;\n    }\n\n    /**\n     * @notice fetch AC coinbase price\n     * @param originBucket_ origin bucket to rebalance\n     * @return AC coinbase price\n     */\n    function _peekACCoinbasePrice(MocOperations originBucket_) internal view returns (uint256) {\n        (bytes32 acCoinbasePrice, bool has) = acCoinbasePriceProvider[originBucket_].peek();\n        if (!has) revert MissingProviderPrice(address(acCoinbasePriceProvider[originBucket_]));\n        return uint256(acCoinbasePrice);\n    }\n\n    /**\n     * @notice calculates qAC and qTP to rebalance\n     * @param originBucket_ origin bucket to rebalance\n     * @param targetBucket_ target bucket to rebalance\n     * @param targetTP_ target TP to rebalance\n     * @param targetBucketCglb_ target bucket coverage [PREC]\n     * @param targetBucketThrld_ threshold to limit the amount of TP available to mint on target bucket\n     * @param isMicroLiquidation_ true if it is a micro liquidation\n     * @param baseGasPrice_ base gas price you want the execFee calculation to use\n     * @return mocSwapper swapper contract to use\n     * @return tokenIn token to send\n     * @return tokenOut token to receive\n     * @return qACToSwap amount of AC from origin bucket to swap\n     * @return qTPToRebalance amount of TP to rebalance\n     * @return qACmin minimum amount of AC to receive on the swap\n     * @return qACExecFee amount of AC for execution fee\n     */\n    function _calcACAndTPtoRebalance(\n        MocOperations originBucket_,\n        MocOperations targetBucket_,\n        address targetTP_,\n        uint256 targetBucketCglb_,\n        uint256 targetBucketThrld_,\n        bool isMicroLiquidation_,\n        uint256 baseGasPrice_\n    )\n        internal\n        view\n        returns (\n            IMocSwapper mocSwapper,\n            address tokenIn,\n            address tokenOut,\n            uint256 qACToSwap,\n            uint256 qTPToRebalance,\n            uint256 qACmin,\n            uint256 qACExecFee\n        )\n    {\n        mocSwapper = mocSwappers[originBucket_][targetBucket_];\n        tokenIn = originBucket_.acToken();\n        tokenOut = targetBucket_.acToken();\n        uint256 maxACtoSwap = mocSwapper.getSafeMaxAmountToSwap(tokenIn, tokenOut);\n        uint256 acCoinbasePrice = tokenIn != COINBASE ? _peekACCoinbasePrice(originBucket_) : ONE;\n        uint256 pACtp = originBucket_.getPACtp(targetTP_);\n        uint256 targetBucketPACtp = targetBucket_.getPACtp(targetTP_);\n        uint256 totalACavailable = originBucket_.getTotalACavailable();\n        uint256 lckAC = originBucket_.getLckAC();\n\n        // Calculate the max amount of TP to rebalance\n        qTPToRebalance = Math.min(\n            originBucket_.getNTP(targetTP_),\n            _calcTPAvailableTargetBucket(targetBucket_, targetBucketCglb_, targetBucketPACtp, targetBucketThrld_)\n        );\n\n        if (isMicroLiquidation_) {\n            uint256 originBucketThrld = rtcThrld[originBucket_];\n            // [N] = [N] * [PREC] / [PREC]\n            qACExecFee = _divPrec(microLiquidationExecCost * baseGasPrice_, acCoinbasePrice);\n            // [PREC] = [PREC] + [PREC]\n            uint256 onePlusPR = ONE + penaltyRate[originBucket_];\n            // calculates the amount of AC to reach the target RTC coverage\n            // [N] = [PREC] * [N] + [N] * [PREC] - [N] * [PREC] / [PREC] - [PREC]\n            uint256 qACOnTP = (originBucketThrld * lckAC + qACExecFee * PRECISION - totalACavailable * PRECISION) /\n                (originBucketThrld - onePlusPR);\n\n            // [N] = [N] * [PREC] / [PREC]\n            uint256 maxACAvailableOnTP = _divPrec(qTPToRebalance, pACtp);\n            // if there is a TP limit on the origin or target bucket we use that amount of AC instead\n            if (qACOnTP > maxACAvailableOnTP) {\n                qACOnTP = maxACAvailableOnTP;\n            } else {\n                // [N] = [N] * [PREC] / [PREC]\n                qTPToRebalance = _mulPrec(qACOnTP, pACtp);\n            }\n\n            // [N] = [N] * [PREC] / [PREC]\n            qACToSwap = _mulPrec(qACOnTP, onePlusPR);\n            if (qACToSwap > maxACtoSwap) {\n                qACToSwap = maxACtoSwap;\n                // [N] = [N] * [PREC] / [PREC]\n                qTPToRebalance = (qACToSwap * pACtp) / onePlusPR;\n            }\n            // we send AC increased by the penalty rate, so that is the slippage allowed in the swap\n            // [N] = [N] * [PREC] / [PREC]\n            qACmin = _divPrec(qTPToRebalance, targetBucketPACtp);\n        } else {\n            // [N] = [N] * [PREC] / [PREC]\n            qACExecFee = _divPrec(liquidationExecCost * baseGasPrice_, acCoinbasePrice);\n            // prevent underflow in extreme cases where the exec fee is higher than the total AC available in the bucket\n            if (qACExecFee >= totalACavailable) qACExecFee = 0;\n            // calculates TP liquidation price\n            // [PREC] = [PREC] * [N] / ([N] - [N])\n            uint256 tpLiqPrice = (pACtp * lckAC) / (totalACavailable - qACExecFee);\n            // [N] = [N] * [PREC] / [PREC]\n            qACToSwap = _divPrec(qTPToRebalance, tpLiqPrice);\n\n            // if there is a AC limit on the max amount allowed to swap parameter we use it instead\n            if (qACToSwap > maxACtoSwap) {\n                qACToSwap = maxACtoSwap;\n                // [N] = [N] * [PREC] / [PREC]\n                qTPToRebalance = _mulPrec(qACToSwap, tpLiqPrice);\n            }\n            // if we are removing all the AC from the bucket, ensure do not revert by underflow due rounding errors\n            if (qACToSwap + qACExecFee > totalACavailable) {\n                // if qACExecFee is 0 or very low, it may not be enough to absorb rounding error\n                if (totalACavailable > qACToSwap) {\n                    // the difference is absorbed on the qACExecFee\n                    qACExecFee = totalACavailable - qACToSwap;\n                } else {\n                    qACToSwap = totalACavailable;\n                    qACExecFee = 0;\n                }\n            }\n            // in a liquidation scenario where coverage < 1, the qAC sent will be less than the TP-equivalent value.\n            // as a result, the target bucket must absorb the loss. We use the normalization factor  to determine the\n            // equivalence between both ACs and apply the penalty rate percentage as slippage in the swap.\n            // [N] = [N] * [PREC] * ([PREC] - [PREC]) / [PREC²]\n            qACmin = (qACToSwap * pACtp * (ONE - penaltyRate[targetBucket_])) / (targetBucketPACtp * PRECISION);\n        }\n        return (mocSwapper, tokenIn, tokenOut, qACToSwap, qTPToRebalance, qACmin, qACExecFee);\n    }\n\n    /**\n     * @notice moves AC and TP from `originBucket_` to `targetBucket_'\n     * @param originBucket_ origin bucket to rebalance\n     * @param targetBucket_ target bucket to rebalance\n     * @param tokenIn_ token to send\n     * @param tokenOut_ token to receive\n     * @param mocSwapper_ swapper contract to use\n     * @param targetTP_ target TP to rebalance\n     * @param qACtoSwap_ amount of AC from origin bucket to swap\n     * @param qTPtoRebalance_ amount of TP to rebalance\n     * @param qACmin_ minimum amount of AC to receive on the swap\n     * @param qACExecFee_ amount of AC for execution fee\n     * @return qACOut amount of AC sent to target bucket\n     */\n    function _rebalanceBuckets(\n        MocOperations originBucket_,\n        MocOperations targetBucket_,\n        address tokenIn_,\n        address tokenOut_,\n        IMocSwapper mocSwapper_,\n        address targetTP_,\n        uint256 qACtoSwap_,\n        uint256 qTPtoRebalance_,\n        uint256 qACmin_,\n        uint256 qACExecFee_\n    ) internal returns (uint256 qACOut) {\n        // subtract TP and AC from the origin bucket. AC is sent to this address\n        originBucket_.rebalance(targetTP_, qTPtoRebalance_, qACtoSwap_ + qACExecFee_);\n\n        if (tokenIn_ == COINBASE) {\n            qACOut = mocSwapper_.swapCoinbase{ value: qACtoSwap_ }(tokenOut_, qACmin_, address(targetBucket_));\n            _coinbaseTransfer(qACExecFee_, coinbaseExecFeeRecipient);\n        } else {\n            SafeERC20.forceApprove(IERC20(tokenIn_), address(mocSwapper_), qACtoSwap_);\n            qACOut = mocSwapper_.swapRC20(tokenIn_, tokenOut_, qACtoSwap_, qACmin_, address(targetBucket_));\n            SafeERC20.safeTransfer(IERC20(tokenIn_), rebalanceExecFeeRecipient[originBucket_], qACExecFee_);\n        }\n\n        // add TP to the target bucket\n        targetBucket_.acceptRebalance(targetTP_, qTPtoRebalance_);\n        // take account the injected collateral\n        targetBucket_.refreshACBalance();\n    }\n\n    /**\n     * @notice set liquidated and remove bucket form the multi collateral protocol\n     * @param bucket_ bucket to remove and liquidate\n     */\n    function _liquidateAndRemoveBucket(MocOperations bucket_) internal {\n        bucket_.setLiquidated();\n        BucketIndex storage iBucketLiquidated = bucketIndex[bucket_];\n        emit BucketLiquidated(address(bucket_));\n\n        // the last bucket cannot be removed from the buckets array because view function will fail\n        // and executeLiquidatedBucket will be useless. If this situation arises, it is recommended to deploy\n        // an entirely new protocol to get back in the game.\n        if (buckets.length == 1) {\n            iBucketLiquidated.exists = false;\n            iBucketLiquidated.liquidated = true;\n            return;\n        }\n\n        MocOperations bucketToMove = buckets[buckets.length - 1];\n\n        // move last bucket to the new index on the array\n        buckets[iBucketLiquidated.index] = bucketToMove;\n        // set new array index\n        bucketIndex[bucketToMove].index = iBucketLiquidated.index;\n        // reset bucket removed index\n        iBucketLiquidated.index = 0;\n        iBucketLiquidated.exists = false;\n        iBucketLiquidated.liquidated = true;\n\n        // remove last item from the array\n        buckets.pop();\n    }\n\n    /**\n     * @notice verifies if liquidation threshold has been reached and liq is enabled on `originBucket_`\n     * @param originBucket_ origin bucket to verify\n     * @param bucketCglb_  bucket current coverage [PREC]\n     * @return true if liquidation threshold is reached, false otherwise\n     */\n    function _evalLiquidation(MocOperations originBucket_, uint256 bucketCglb_) internal view returns (bool) {\n        return originBucket_.liqEnabled() && bucketCglb_ <= originBucket_.liqThrld();\n    }\n\n    // ------- External Functions -------\n\n    /**\n     * @notice verifies if bucket micro liquidation is available,\n     *  checking if bucket coverage > liquidation && bucket coverage <= micro liquidation\n     * @param originBucket_ origin bucket to verify\n     * @return true if micro liquidation threshold is reached, false otherwise\n     */\n    function isMicroLiquidationAvailable(MocOperations originBucket_) public view returns (bool) {\n        return isMicroLiquidationAvailableWithPrices(originBucket_, originBucket_.getPACtps());\n    }\n\n    /**\n     * @notice verifies if bucket micro liquidation is available,\n     *  checking if bucket coverage > liquidation && bucket coverage <= micro liquidation\n     * @param originBucket_ origin bucket to verify\n     * @param pACtps_ all tps prices for the given bucket [PREC]\n     * @return true if micro liquidation threshold is reached, false otherwise\n     */\n    function isMicroLiquidationAvailableWithPrices(\n        MocOperations originBucket_,\n        uint256[] memory pACtps_\n    ) public view returns (bool) {\n        uint256 cglb = originBucket_.calcCglb(pACtps_);\n        return (cglb > originBucket_.liqThrld() && cglb <= microLiquidationThrld[originBucket_]);\n    }\n\n    /**\n     * @notice verifies if liquidation threshold has been reached and liq is enabled on `originBucket_`\n     * @param originBucket_ origin bucket to verify\n     * @return true if liquidation threshold is reached, false otherwise\n     */\n    function isLiquidationAvailable(MocOperations originBucket_) public view returns (bool) {\n        return isLiquidationAvailableWithPrices(originBucket_, originBucket_.getPACtps());\n    }\n\n    /**\n     * @notice verifies if liquidation threshold has been reached and liq is enabled on `originBucket_`\n     * @param originBucket_ origin bucket to verify\n     * @param pACtps_ all tps prices for the given bucket [PREC]\n     * @return true if liquidation threshold is reached, false otherwise\n     */\n    function isLiquidationAvailableWithPrices(\n        MocOperations originBucket_,\n        uint256[] memory pACtps_\n    ) public view returns (bool) {\n        return _evalLiquidation(originBucket_, originBucket_.calcCglb(pACtps_)) && !originBucket_.liquidated();\n    }\n\n    /**\n     * @notice gets qAC and qTP to rebalance on a micro liquidation\n     * @param originBucket_ origin bucket to rebalance\n     * @param baseGasPrice_ base gas price you want the execFee calculation to use, zero for network basefee\n     * @return targetBucket target bucket to rebalance\n     * @return targetTP target TP to rebalance\n     * @return qACToSwap amount of AC from origin bucket to swap\n     * @return qTPToRebalance amount of TP to rebalance\n     * @return qACExecFee amount of AC for execution fee\n     */\n    function getACAndTPtoRebalanceOnMicroLiquidation(\n        MocOperations originBucket_,\n        uint256 baseGasPrice_\n    )\n        external\n        view\n        returns (\n            MocOperations targetBucket,\n            address targetTP,\n            uint256 qACToSwap,\n            uint256 qTPToRebalance,\n            uint256 qACExecFee\n        )\n    {\n        if (!isMicroLiquidationAvailable(originBucket_)) return (MocOperations(address(0)), address(0), 0, 0, 0);\n        uint256 targetBucketCglb;\n        (targetBucket, targetBucketCglb) = _calcTargetBucketToRebalanceOnMicroLiquidation(originBucket_, buckets);\n        if (address(targetBucket) == address(0)) return (MocOperations(address(0)), address(0), 0, 0, 0);\n        targetTP = _getTPMostLockedAC(originBucket_);\n\n        (, , , qACToSwap, qTPToRebalance /*qACmin*/, , qACExecFee) = _calcACAndTPtoRebalance(\n            originBucket_,\n            targetBucket,\n            targetTP,\n            targetBucketCglb,\n            rtcThrld[targetBucket],\n            true /*isMicroLiquidation == true*/,\n            baseGasPrice_ == 0 ? block.basefee : baseGasPrice_\n        );\n        return (targetBucket, targetTP, qACToSwap, qTPToRebalance, qACExecFee);\n    }\n\n    /**\n     * @notice gets qAC and qTP to rebalance on a liquidation\n     * @param originBucket_ origin bucket to liquidate\n     * @param baseGasPrice_ base gas price you want the execFee calculation to use, zero for network basefee\n     * @return targetBucket target bucket to receive liquidation\n     * @return targetTP target TP to rebalance\n     * @return qACToSwap amount of AC from origin bucket to swap\n     * @return qTPToRebalance amount of TP to rebalance\n     * @return qACExecFee amount of AC for execution fee\n     */\n    function getACAndTPtoRebalanceOnLiquidation(\n        MocOperations originBucket_,\n        uint256 baseGasPrice_\n    )\n        external\n        view\n        returns (\n            MocOperations targetBucket,\n            address targetTP,\n            uint256 qACToSwap,\n            uint256 qTPToRebalance,\n            uint256 qACExecFee\n        )\n    {\n        if (!isLiquidationAvailable(originBucket_)) return (MocOperations(address(0)), address(0), 0, 0, 0);\n        uint256 targetBucketCglb;\n        uint256 thrld;\n        (targetBucket, targetBucketCglb, thrld) = _calcTargetBucketToRebalanceOnLiquidation(originBucket_, buckets);\n        if (address(targetBucket) == address(0)) return (MocOperations(address(0)), address(0), 0, 0, 0);\n        targetTP = _getTPMostLockedAC(originBucket_);\n\n        (, , , qACToSwap, qTPToRebalance /*qACmin*/, , qACExecFee) = _calcACAndTPtoRebalance(\n            originBucket_,\n            targetBucket,\n            targetTP,\n            targetBucketCglb,\n            thrld,\n            false /*isMicroLiquidation == false*/,\n            baseGasPrice_ == 0 ? block.basefee : baseGasPrice_\n        );\n        return (targetBucket, targetTP, qACToSwap, qTPToRebalance, qACExecFee);\n    }\n\n    /**\n     * @notice execute micro liquidation on `originBucket_`\n     * @param originBucket_ origin bucket to rebalance\n     */\n    // slither-disable-next-line reentrancy-no-eth\n    function execMicroLiquidation(MocOperations originBucket_) external notPaused nonReentrant {\n        BucketIndex storage iBucket = bucketIndex[originBucket_];\n        if (!iBucket.exists) revert BucketDoesNotExist();\n        // Before evaluating micro liquidation, we need to make sure injected collateral is accounted\n        originBucket_.refreshACBalance();\n        if (!isMicroLiquidationAvailable(originBucket_)) revert MicroLiquidationNotAvailable();\n\n        (MocOperations targetBucket, uint256 targetBucketCglb) = _getTargetBucketToRebalanceOnMicroLiquidation(\n            originBucket_\n        );\n        if (address(targetBucket) == address(0)) revert NoTargetBucketAvailableToRebalance();\n\n        address targetTP = _getTPMostLockedAC(originBucket_);\n        (\n            IMocSwapper mocSwapper,\n            address tokenIn,\n            address tokenOut,\n            uint256 qACToSwap,\n            uint256 qTPToRebalance,\n            uint256 qACmin,\n            uint256 qACExecFee\n        ) = _calcACAndTPtoRebalance(\n                originBucket_,\n                targetBucket,\n                targetTP,\n                targetBucketCglb,\n                rtcThrld[targetBucket],\n                true /*isMicroLiquidation == true*/,\n                block.basefee\n            );\n\n        uint256 qACOut = _rebalanceBuckets(\n            originBucket_,\n            targetBucket,\n            tokenIn,\n            tokenOut,\n            mocSwapper,\n            targetTP,\n            qACToSwap,\n            qTPToRebalance,\n            qACmin,\n            qACExecFee\n        );\n\n        emit MicroLiquidationExecuted(\n            msg.sender,\n            address(originBucket_),\n            address(targetBucket),\n            address(targetTP),\n            qACToSwap,\n            qACOut,\n            qTPToRebalance,\n            qACExecFee\n        );\n    }\n\n    /**\n     * @notice execute liquidation if threshold has been reached and liq is enabled on `originBucket_`\n     * @param originBucket_ origin bucket to evaluate liquidation\n     */\n    // slither-disable-next-line reentrancy-no-eth\n    function execLiquidation(MocOperations originBucket_) external notPaused nonReentrant {\n        BucketIndex storage iBucket = bucketIndex[originBucket_];\n        if (!iBucket.exists) revert BucketDoesNotExist();\n        // Before evaluating liquidation, we need to make sure injected collateral is accounted\n        originBucket_.refreshACBalance();\n        if (!isLiquidationAvailable(originBucket_)) revert LiquidationNotAvailable();\n\n        // if it is the only bucket available execute the single liquidation\n        if (buckets.length == 1) {\n            originBucket_.liquidate();\n            _liquidateAndRemoveBucket(originBucket_);\n        } else {\n            (\n                MocOperations targetBucket,\n                uint256 targetBucketCglb,\n                uint256 thrld\n            ) = _getTargetBucketToRebalanceOnLiquidation(originBucket_);\n            address targetTP = _getTPMostLockedAC(originBucket_);\n            (\n                IMocSwapper mocSwapper,\n                address tokenIn,\n                address tokenOut,\n                uint256 qACToSwap,\n                uint256 qTPToRebalance,\n                uint256 qACmin,\n                uint256 qACExecFee\n            ) = _calcACAndTPtoRebalance(\n                    originBucket_,\n                    targetBucket,\n                    targetTP,\n                    targetBucketCglb,\n                    thrld,\n                    false /*isMicroLiquidation == false*/,\n                    block.basefee\n                );\n            uint256 qACOut = _rebalanceBuckets(\n                originBucket_,\n                targetBucket,\n                tokenIn,\n                tokenOut,\n                mocSwapper,\n                targetTP,\n                qACToSwap,\n                qTPToRebalance,\n                qACmin,\n                qACExecFee\n            );\n            emit PartialLiquidationExecuted(\n                msg.sender,\n                address(originBucket_),\n                address(targetBucket),\n                address(targetTP),\n                qACToSwap,\n                qACOut,\n                qTPToRebalance,\n                qACExecFee\n            );\n\n            // if bucket is empty set liquidated and remove it from the protocol\n            if (originBucket_.getLckAC() == 0) {\n                _liquidateAndRemoveBucket(originBucket_);\n            }\n        }\n    }\n\n    // ------- Only Authorized Functions -------\n\n    /**\n     * @notice sets micro liquidation execution cost\n     * @param microLiquidationExecCost_ coinbase micro liquidation execution fee. Paid from the\n     *  rebalanced bucket to the executor\n     */\n    function setMicroLiquidationExecCost(uint256 microLiquidationExecCost_) external onlyAuthorizedChanger {\n        microLiquidationExecCost = microLiquidationExecCost_;\n    }\n\n    /**\n     * @notice sets liquidation execution cost\n     * @param liquidationExecCost_ coinbase liquidation execution fee. Paid from the liquidated bucket to the executor\n     */\n    function setLiquidationExecCost(uint256 liquidationExecCost_) external onlyAuthorizedChanger {\n        liquidationExecCost = liquidationExecCost_;\n    }\n\n    /**\n     * @notice sets mocSwapper for a given pair of buckets\n     * @param bucketA_ bucket to set the new mocSwapper\n     * @param bucketB_ bucket to set the new mocSwapper\n     * @param mocSwapper_ mocSwapper contract to swap the bucketA_ / bucketB_ pool\n     */\n    function setMocSwapper(\n        MocOperations bucketA_,\n        MocOperations bucketB_,\n        IMocSwapper mocSwapper_\n    ) external onlyAuthorizedChanger {\n        mocSwappers[bucketA_][bucketB_] = mocSwapper_;\n        mocSwappers[bucketB_][bucketA_] = mocSwapper_;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/interfaces/draft-IERC1822.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n    /**\n     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n     * address.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy.\n     */\n    function proxiableUUID() external view returns (bytes32);\n}\n"},{"file_path":"project/contracts/changers/rifProMigrationChanger/RifPRoMigrationChanger.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IChangeContract } from \"moc-main-latest/contracts/interfaces/IChangeContract.sol\";\nimport { MocRif } from \"../../MocRif.sol\";\nimport { TokenMigrator } from \"../../TokenMigrator.sol\";\n\ninterface IAccessControl {\n    function hasRole(bytes32 role_, address account_) external view returns (bool);\n}\n\ninterface IMocQueue {\n    function isEmpty() external view returns (bool);\n}\n\n/**\n  @title RifPRoMigrationChanger\n  @notice Migrates RIFPro token to the new one\n  @dev Preconditions:\n       - The new RIFPro token must grant MINTER_ROLE, BURNER_ROLE, and DEFAULT_ADMIN_ROLE\n         to the RIF bucket proxy before this change is executed.\n       - The RIF bucket must have fresh valid prices in the execution block, so the new\n         nTCcb and migration rate are calculated from up-to-date bucket state.\n       - The RIF queue must be empty. Pending TC redeem operations can distort the new\n         nTCcb calculation.\n       - The protocol should be paused during execution. Otherwise, an attacker could\n         enqueue operations around the migration and manipulate the TC price.\n */\ncontract RifPRoMigrationChanger is IChangeContract {\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n    bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n    bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n    error MissingTokenRole(bytes32 role_, address account_);\n    error QueueNotEmpty();\n\n    MocRif public immutable rifBucketProxy;\n    address public immutable newRifBucketImplementation;\n    address public immutable legacyRifProToken;\n    address public immutable newRifProToken;\n    TokenMigrator public tokenMigrator;\n\n    constructor(\n        address rifBucketProxy_,\n        address newRifBucketImplementation_,\n        address legacyRifProToken_,\n        address newRifProToken_\n    ) {\n        rifBucketProxy = MocRif(rifBucketProxy_);\n        newRifBucketImplementation = newRifBucketImplementation_;\n        legacyRifProToken = legacyRifProToken_;\n        newRifProToken = newRifProToken_;\n    }\n\n    function execute() external {\n        _beforeUpgrade();\n        _upgrade();\n        _afterUpgrade();\n    }\n\n    function _upgrade() internal {\n        rifBucketProxy.upgradeTo(newRifBucketImplementation);\n    }\n    function _beforeUpgrade() internal view {\n        address rifBucketAddress = address(rifBucketProxy);\n        if (!IMocQueue(rifBucketProxy.mocQueue()).isEmpty()) revert QueueNotEmpty();\n        if (!IAccessControl(newRifProToken).hasRole(MINTER_ROLE, rifBucketAddress))\n            revert MissingTokenRole(MINTER_ROLE, rifBucketAddress);\n        if (!IAccessControl(newRifProToken).hasRole(BURNER_ROLE, rifBucketAddress))\n            revert MissingTokenRole(BURNER_ROLE, rifBucketAddress);\n        if (!IAccessControl(newRifProToken).hasRole(DEFAULT_ADMIN_ROLE, rifBucketAddress))\n            revert MissingTokenRole(DEFAULT_ADMIN_ROLE, rifBucketAddress);\n    }\n    function _afterUpgrade() internal {\n        // Setting this new nTCcb ensures that new RIFpro token price is 1:1 with RIF token\n        uint256 newNTCcb = rifBucketProxy.getTotalACavailable() - rifBucketProxy.getLckAC();\n        // Calculate migration rate based on the new nTCcb and the previous one, so users get the correct amount of new RIFPro tokens according to the new price\n        uint256 migrationRate = (newNTCcb * 1e18) / rifBucketProxy.nTCcb();\n        // Initialize the token migrator with the legacy and new RIFPro token addresses and the calculated migration rate\n        tokenMigrator = new TokenMigrator(legacyRifProToken, newRifProToken, migrationRate);\n        // Set the new RIFPro token and the new nTCcb in the bucket, so it can work with the new token after the upgrade\n        rifBucketProxy.migrateTCToken(newRifProToken, newNTCcb, address(tokenMigrator));\n    }\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/ITask.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\ninterface ITask {\n    /**\n     * @notice Checks if the task can be executed.\n     * @return bool indicating if the task can be executed\n     */\n    function checkTask() external view returns (bool);\n\n    /**\n     * @notice Executes the task.\n     */\n    function runTask() external;\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/multiCollateral/MocMultiCollateralGuard.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocRebalancer, MocOperations } from \"./MocRebalancer.sol\";\nimport { MocQueue } from \"../queue/MocQueue.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\n/**\n * @title MocMultiCollateralGuard\n * @notice this contract serves as a reference source for all buckets to determine the overall state\n * of the multi-collateral system, allowing only operations that maintain it in a healthy state\n */\ncontract MocMultiCollateralGuard is MocRebalancer {\n    // ------- Custom Errors -------\n    error BucketEmpty();\n    error LowCoverage(uint256 cglb_, uint256 covThrld_);\n    error AnyBucketNeedsLiquidation();\n\n    // ------- Storage -------\n\n    // max amount of Operations that can be executed on a single batch,\n    // gas restricted batch size to guarantee no gas limit failure\n    uint256 public maxOperPerBatch;\n    // switches the way that price providers trigger the queue execution using the last publication block\n    // false: use the minimum, so operations enqueued before the oldest price are executed. New operations\n    //  have to wait until all the prices are updated\n    // true: use the maximum, so operations enqueued before the newest price are executed. New operations\n    //  have to wait until only one price is updated\n    bool public useMaxLastPublicationBlock;\n    // If queue operations include a price-update fee, this address receives those funds\n    // and is responsible for distributing them to the corresponding oracles.\n    address public priceUpdatesFeeRecipient;\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    // ------- Initializer -------\n\n    /**\n     * @notice contract initializer\n     * @param governor_ governor address\n     * @param pauser_ pauser address\n     * @param microLiquidationExecCost_ coinbase micro liquidation execution fee. Paid from the\n     *  rebalanced bucket to the executor\n     * @param liquidationExecCost_ coinbase liquidation execution fee. Paid from the liquidated bucket to the executor\n     * @param coinbaseExecFeeRecipient_ address who receives all the coinbase execution fees\n     * @param priceUpdatesFeeRecipient_ address that receives queue price-update fees\n     * @param maxOperPerBatch_ max amount of Operations that can be executed on a single batch\n     * @param useMaxLastPublicationBlock_ use max last publication block to trigger the queue execution\n     */\n    function initialize(\n        address governor_,\n        address pauser_,\n        uint256 microLiquidationExecCost_,\n        uint256 liquidationExecCost_,\n        address payable coinbaseExecFeeRecipient_,\n        address priceUpdatesFeeRecipient_,\n        uint256 maxOperPerBatch_,\n        bool useMaxLastPublicationBlock_\n    ) external initializer {\n        __MocUpgradable_init(governor_, pauser_);\n        __ReentrancyGuard_init();\n        __MocRebalancer_init(microLiquidationExecCost_, liquidationExecCost_, coinbaseExecFeeRecipient_);\n        priceUpdatesFeeRecipient = priceUpdatesFeeRecipient_;\n        maxOperPerBatch = maxOperPerBatch_;\n        useMaxLastPublicationBlock = useMaxLastPublicationBlock_;\n    }\n\n    // ------- Internal Functions -------\n\n    /**\n     * @notice calculates the AC price ratio between `baseBucket_ and `bucketTo_`\n     * @dev nf = pACtpBase / pACtpTo\n     *  we use the median of all the TP prices in order to discard outliers\n     * @param pACtpsTo_ array of all AC prices for each TP for target bucket [PREC]\n     * @param baseBucket_ base bucket\n     * @param bucketTo_ target bucket to calculate the price ratio of, in relation to the base bucket\n     * @return nf normalization factor [PREC]\n     */\n    function _calcBucketNormalizationFactor(\n        uint256[] memory pACtpsBaseBucket_,\n        uint256[] memory pACtpsTo_,\n        MocOperations baseBucket_,\n        MocOperations bucketTo_\n    ) internal view returns (uint256 nf) {\n        for (uint256 i = 0; i < pACtpsTo_.length; i = unchecked_inc(i)) {\n            address tpAddress = address(bucketTo_.tpTokens(i));\n            (uint256 index, ) = baseBucket_.peggedTokenIndex(tpAddress);\n            // [PREC] = [PREC] * [PREC] / [PREC]\n            nf += _divPrec(pACtpsTo_[i], pACtpsBaseBucket_[index]);\n        }\n        // [PREC] = [PREC] / [N]\n        nf /= pACtpsTo_.length;\n        return nf;\n    }\n\n    /**\n     * @notice transfer coinbase to the recipient\n     * @dev reverts if coinbase transfer fails\n     * @param amount_ amount to transfer\n     * @param recipient_ address of the recipient\n     */\n    function _payCoinbase(uint256 amount_, address recipient_) internal {\n        // if execution fees were increased before the execution, the balance could not be enough\n        // to pay the required, so, the recipient will receive everything that the contract has\n        if (amount_ > address(this).balance) amount_ = address(this).balance;\n        _coinbaseTransfer(amount_, recipient_);\n    }\n\n    /**\n     * @notice gets all TP prices for each bucket\n     * @param buckets_ buckets array\n     * @return bucketsPACtps All tps prices [PREC]\n     */\n    function _getBucketsPACtps(\n        MocOperations[] memory buckets_\n    ) internal view returns (uint256[][] memory bucketsPACtps) {\n        bucketsPACtps = new uint256[][](buckets_.length);\n        for (uint256 j = 0; j < buckets_.length; j = unchecked_inc(j)) {\n            bucketsPACtps[j] = buckets_[j].getPACtps();\n        }\n    }\n\n    /**\n     * @notice calc all bucket normalization factors\n     * @param buckets_ buckets array\n     * @param bucketsPACtps_ all tps prices for each bucket [PREC]\n     * @return normalizationFactors array of normalization factors [PREC]\n     */\n    function _calcNormalizationFactors(\n        MocOperations[] memory buckets_,\n        uint256[][] memory bucketsPACtps_\n    ) internal view returns (uint256[] memory normalizationFactors) {\n        normalizationFactors = new uint256[](buckets_.length);\n        normalizationFactors[0] = PRECISION;\n        for (uint256 j = 1; j < buckets_.length; j = unchecked_inc(j)) {\n            normalizationFactors[j] = _calcBucketNormalizationFactor(\n                bucketsPACtps_[0],\n                bucketsPACtps_[j],\n                buckets_[0],\n                buckets_[j]\n            );\n        }\n    }\n\n    /**\n     * @notice gets all buckets combined coverage\n     *  combinedCglb = (Σ cglb(i) * lckACNormalized(i)) / Σ lckACNormalized(i)\n     * @param buckets_ buckets array\n     * @param bucketsPACtps_ all tps prices for each bucket [PREC]\n     * @param normalizationFactors_ array of normalization factors [PREC]\n     * @return combinedCglb combined coverage [PREC]\n     */\n    function _calcCombinedCglb(\n        MocOperations[] memory buckets_,\n        uint256[][] memory bucketsPACtps_,\n        uint256[] memory normalizationFactors_\n    ) internal view returns (uint256 combinedCglb) {\n        uint256 num;\n        uint256 den;\n        for (uint256 j = 0; j < buckets_.length; j = unchecked_inc(j)) {\n            MocOperations bucket = buckets_[j];\n            (uint256 bucketCglb, uint256 bucketLckAC) = bucket.calcCglbAndLckAC(bucketsPACtps_[j]);\n            // empty buckets are not considered to calculate combined coverage\n            if (bucketCglb != UINT256_MAX) {\n                // [PREC] = [N] * [PREC]\n                uint256 lckACNormalized = bucketLckAC * normalizationFactors_[j];\n                // [PREC]² = [PREC] + [PREC] * [PREC]\n                num += bucketCglb * lckACNormalized;\n                // [PREC] = [PREC] + [PREC]\n                den += lckACNormalized;\n            }\n        }\n        // if all the buckets are empty\n        if (den == 0) return UINT256_MAX;\n        // [PREC] = [PREC]² / [PREC]\n        combinedCglb = num / den;\n        return combinedCglb;\n    }\n\n    /**\n     * @notice gets all buckets target coverage adjusted by Ema\n     *  combinedCtargemaCA = (Σ ctargemaCA(i) * lckACNormalized(i)) / Σ lckACNormalized(i)\n     * @param buckets_ buckets array\n     * @param bucketsPACtps_ all tps prices for each bucket [PREC]\n     * @param normalizationFactors_ normalization factors array\n     * @return combinedCtargemaCA combined ctargemaCA [PREC]\n     */\n    function _calcCombinedCtargemaCA(\n        MocOperations[] memory buckets_,\n        uint256[][] memory bucketsPACtps_,\n        uint256[] memory normalizationFactors_\n    ) internal view returns (uint256 combinedCtargemaCA) {\n        uint256 num;\n        uint256 den;\n        for (uint256 j = 0; j < buckets_.length; j = unchecked_inc(j)) {\n            MocOperations bucket = buckets_[j];\n            uint256 bucketLckAC = bucket.calcLckAC(bucketsPACtps_[j]);\n            uint256 ctargemaCA = bucket.calcCtargemaCA(bucketsPACtps_[j]);\n            // [PREC] = [N] * [PREC]\n            uint256 lckACNormalized = bucketLckAC * normalizationFactors_[j];\n            // [PREC]² = [PREC] + [PREC] * [PREC]\n            num += ctargemaCA * lckACNormalized;\n            // [PREC] = [PREC] + [PREC]\n            den += lckACNormalized;\n        }\n        // we must return a default value when all nTP are 0\n        // slither-disable-next-line incorrect-equality\n        if (den == 0) {\n            return buckets[0].protThrld() * 2;\n        }\n        // [PREC] = [PREC]² / [PREC]\n        combinedCtargemaCA = num / den;\n        return combinedCtargemaCA;\n    }\n\n    /**\n     * @notice gets the real TC available to redeem considering all buckets status\n     * @dev this function only is valid when it is called by a bucket\n     * @param bucket_ bucket that is intended to operate\n     * @param buckets_ buckets array\n     * @param bucketsPACtps_ all tps prices for each bucket [PREC]\n     * @param normalizationFactors_ array of normalization factors [PREC]\n     * @return realTCAvailableToRedeem real TC available to redeem [N]\n     */\n    function _calcRealTCAvailableToRedeem(\n        MocOperations bucket_,\n        MocOperations[] memory buckets_,\n        uint256[][] memory bucketsPACtps_,\n        uint256[] memory normalizationFactors_\n    ) internal view returns (uint256 realTCAvailableToRedeem) {\n        uint256 localTCAvailableToRedeem;\n        int256 lckACemaAdjustedSigned;\n        uint256 pTCacNormalized;\n        for (uint256 j = 0; j < buckets_.length; j = unchecked_inc(j)) {\n            MocOperations currBucket = buckets_[j];\n            // [PREC]² = [PREC] * [PREC]\n            lckACemaAdjustedSigned +=\n                currBucket.calcLckACemaAdjusted(bucketsPACtps_[j]) *\n                int256(normalizationFactors_[j]);\n            if (currBucket == bucket_) {\n                localTCAvailableToRedeem = currBucket.calcTCAvailableToRedeem(bucketsPACtps_[j]);\n                if (localTCAvailableToRedeem == 0) return 0;\n                // [PREC]² = [PREC] * [PREC]\n                pTCacNormalized = currBucket.calcPTCac(bucketsPACtps_[j]) * normalizationFactors_[j];\n            }\n        }\n        if (lckACemaAdjustedSigned <= 0 || pTCacNormalized == 0) return 0;\n        // [N] = [PREC]² / [PREC]²\n        realTCAvailableToRedeem = uint256(lckACemaAdjustedSigned) / pTCacNormalized;\n        // [N]\n        return Math.min(realTCAvailableToRedeem, localTCAvailableToRedeem);\n    }\n\n    /**\n     * @notice gets the real TP available to mint considering all buckets status\n     * @dev this function only is valid when it is called by a bucket\n     * @param bucket_ bucket that is intended to operate\n     * @param tp_ Pegged Token address\n     * @param buckets_ buckets array\n     * @param bucketsPACtps_ all tps prices for each bucket [PREC]\n     * @return realTPAvailableToMint real TP available to mint [N]\n     */\n    function _calcRealTPAvailableToMint(\n        MocOperations bucket_,\n        address tp_,\n        MocOperations[] memory buckets_,\n        uint256[][] memory bucketsPACtps_\n    ) internal view returns (uint256 realTPAvailableToMint) {\n        int256 localTPAvailableToMintSigned;\n        int256 realTPAvailableToMintSigned;\n        for (uint256 j = 0; j < buckets_.length; j = unchecked_inc(j)) {\n            MocOperations currBucket = buckets_[j];\n            if (currBucket != bucket_) {\n                // if TP doesn't exist in the others bucket is not taking on account\n                (, bool exists) = currBucket.peggedTokenIndex(tp_);\n                // [N] = [N] + [N]\n                if (exists) realTPAvailableToMintSigned += currBucket.calcTPAvailableToMint(tp_, bucketsPACtps_[j]);\n            } else {\n                localTPAvailableToMintSigned = currBucket.calcTPAvailableToMint(tp_, bucketsPACtps_[j]);\n                // [N] = [N] + [N]\n                realTPAvailableToMintSigned += localTPAvailableToMintSigned;\n            }\n        }\n        if (realTPAvailableToMintSigned <= 0 || localTPAvailableToMintSigned <= 0) return 0;\n        // [N]\n        return Math.min(uint256(realTPAvailableToMintSigned), uint256(localTPAvailableToMintSigned));\n    }\n\n    /**\n     * @notice calculate if any bucket needs liquidation\n     * @param buckets_ buckets array\n     * @param bucketsPACtps_ all tps prices for each bucket [PREC]\n     * @return true if any bucket needs liquidation\n     */\n    function _calcAnyBucketNeedsLiquidation(\n        MocOperations[] memory buckets_,\n        uint256[][] memory bucketsPACtps_\n    ) internal view returns (bool) {\n        // We only run this check when there is more than one bucket.\n        // With a single bucket, it is always the \"last\" bucket, so the check is redundant.\n        if (buckets_.length <= 1) return false;\n\n        for (uint256 j = 0; j < buckets_.length; j = unchecked_inc(j)) {\n            MocOperations bucket = buckets_[j];\n            if (_evalLiquidation(bucket, bucket.calcCglb(bucketsPACtps_[j]))) return true;\n        }\n        return false;\n    }\n\n    /**\n     * @notice get the min or max last TP price publication block among all the buckets\n     * @param buckets_ buckets array\n     * @param useMaxLastPublicationBlock_ use the max last publication block to trigger the queue execution\n     * @return lastPublicationBlock the min or max last block where there was a price publication\n     */\n    function _getLastPublicationBlock(\n        MocOperations[] memory buckets_,\n        bool useMaxLastPublicationBlock_\n    ) internal view returns (uint256 lastPublicationBlock) {\n        lastPublicationBlock = buckets_[0].getLastPublicationBlock(useMaxLastPublicationBlock_);\n        for (uint256 j = 1; j < buckets_.length; j = unchecked_inc(j)) {\n            uint256 bucketLastPublicationBlock = buckets_[j].getLastPublicationBlock(useMaxLastPublicationBlock_);\n            lastPublicationBlock = useMaxLastPublicationBlock_\n                ? Math.max(lastPublicationBlock, bucketLastPublicationBlock)\n                : Math.min(lastPublicationBlock, bucketLastPublicationBlock);\n        }\n    }\n\n    /**\n     * @notice evaluates whether or not the coverage is over the cThrld_, reverts if below\n     * @param cThrld_ coverage threshold to check for [PREC]\n     */\n    function _evalCombinedCoverage(uint256 combinedCglb_, uint256 cThrld_) internal pure {\n        // check if coverage is above the given threshold\n        if (combinedCglb_ < cThrld_) revert LowCoverage(combinedCglb_, cThrld_);\n    }\n\n    // ------- External Functions -------\n\n    /**\n     * @notice get combined coverage and combined ctargemaCA\n     * @param bucket_ bucket that is intended to operate\n     * @return combinedCglb combined coverage [PREC]\n     * @return combinedCtargemaCA combined ctargemaCA [PREC]\n     * @return bucketPACtps all tps prices for the given bucket [PREC]\n     */\n    function getCombinedValues(\n        MocOperations bucket_\n    ) external returns (uint256 combinedCglb, uint256 combinedCtargemaCA, uint256[] memory bucketPACtps) {\n        MocOperations[] memory bucketsArray = buckets;\n        uint256[][] memory bucketsPACtps = _getBucketsPACtps(bucketsArray);\n\n        // If any bucket is pending liquidation, redeemTC is disabled.\n        // Otherwise, users could redeem before liquidation at a TC price\n        // that does not reflect the cost of absorbing losses from another bucket.\n        if (_calcAnyBucketNeedsLiquidation(bucketsArray, bucketsPACtps)) revert AnyBucketNeedsLiquidation();\n\n        uint256[] memory normalizationFactors = _calcNormalizationFactors(bucketsArray, bucketsPACtps);\n        _updatesCtargemaCA(bucketsArray);\n        return (\n            _calcCombinedCglb(bucketsArray, bucketsPACtps, normalizationFactors),\n            _calcCombinedCtargemaCA(bucketsArray, bucketsPACtps, normalizationFactors),\n            bucketsPACtps[bucketIndex[bucket_].index]\n        );\n    }\n\n    /**\n     * @notice get combined values and TC available to redeem\n     * @param bucket_ bucket that is intended to operate\n     * @return realTCAvailableToRedeem real TC available to redeem [N]\n     * @return bucketPACtps all tps prices for the given bucket [PREC]\n     */\n    function getCombinedAndTC(\n        MocOperations bucket_\n    ) external returns (uint256 realTCAvailableToRedeem, uint256[] memory bucketPACtps) {\n        MocOperations[] memory bucketsArray = buckets;\n        uint256[][] memory bucketsPACtps = _getBucketsPACtps(bucketsArray);\n\n        // If any bucket is pending liquidation, redeemTC is disabled.\n        // Otherwise, users could redeem before liquidation at a TC price\n        // that does not reflect the cost of absorbing losses from another bucket.\n        if (_calcAnyBucketNeedsLiquidation(bucketsArray, bucketsPACtps)) revert AnyBucketNeedsLiquidation();\n\n        uint256[] memory normalizationFactors = _calcNormalizationFactors(bucketsArray, bucketsPACtps);\n        _updatesCtargemaCA(bucketsArray);\n\n        uint256 combinedCglb = _calcCombinedCglb(bucketsArray, bucketsPACtps, normalizationFactors);\n        uint256 combinedCtargemaCA = _calcCombinedCtargemaCA(bucketsArray, bucketsPACtps, normalizationFactors);\n        _evalCombinedCoverage(combinedCglb, combinedCtargemaCA);\n\n        return (\n            _calcRealTCAvailableToRedeem(bucket_, bucketsArray, bucketsPACtps, normalizationFactors),\n            bucketsPACtps[bucketIndex[bucket_].index]\n        );\n    }\n\n    /**\n     * @notice get combined values and TP available to mint\n     * @param bucket_ bucket that is intended to operate\n     * @param tp_ Pegged Token that is intended to operate\n     * @return realTPAvailableToMint real TP available to mint [N]\n     * @return bucketPACtps all tps prices for the given bucket [PREC]\n     */\n    function getCombinedAndTP(\n        MocOperations bucket_,\n        address tp_\n    ) external returns (uint256 realTPAvailableToMint, uint256[] memory bucketPACtps) {\n        MocOperations[] memory bucketsArray = buckets;\n        uint256[][] memory bucketsPACtps = _getBucketsPACtps(bucketsArray);\n        uint256[] memory normalizationFactors = _calcNormalizationFactors(bucketsArray, bucketsPACtps);\n        _updatesCtargemaCA(bucketsArray);\n\n        uint256 combinedCglb = _calcCombinedCglb(bucketsArray, bucketsPACtps, normalizationFactors);\n        uint256 combinedCtargemaCA = _calcCombinedCtargemaCA(bucketsArray, bucketsPACtps, normalizationFactors);\n        _evalCombinedCoverage(combinedCglb, combinedCtargemaCA);\n\n        return (\n            _calcRealTPAvailableToMint(bucket_, tp_, bucketsArray, bucketsPACtps),\n            bucketsPACtps[bucketIndex[bucket_].index]\n        );\n    }\n\n    /**\n     * @notice get combined values, TC available to redeem and TP available to mint\n     * @param bucket_ bucket that is intended to operate\n     * @param tp_ Pegged Token that is intended to operate\n     * @return realTCAvailableToRedeem real TC available to redeem [N]\n     * @return realTPAvailableToMint real TP available to mint [N]\n     * @return bucketPACtps all tps prices for the given bucket [PREC]\n     */\n    function getCombinedAndTCAndTP(\n        MocOperations bucket_,\n        address tp_\n    ) external returns (uint256 realTCAvailableToRedeem, uint256 realTPAvailableToMint, uint256[] memory bucketPACtps) {\n        MocOperations[] memory bucketsArray = buckets;\n        uint256[][] memory bucketsPACtps = _getBucketsPACtps(bucketsArray);\n\n        // If any bucket is pending liquidation, swapTCforTP is disabled.\n        // Otherwise, users could redeem before liquidation at a TC price\n        // that does not reflect the cost of absorbing losses from another bucket.\n        if (_calcAnyBucketNeedsLiquidation(bucketsArray, bucketsPACtps)) revert AnyBucketNeedsLiquidation();\n\n        uint256[] memory normalizationFactors = _calcNormalizationFactors(bucketsArray, bucketsPACtps);\n        _updatesCtargemaCA(bucketsArray);\n\n        uint256 combinedCglb = _calcCombinedCglb(bucketsArray, bucketsPACtps, normalizationFactors);\n        uint256 combinedCtargemaCA = _calcCombinedCtargemaCA(bucketsArray, bucketsPACtps, normalizationFactors);\n        _evalCombinedCoverage(combinedCglb, combinedCtargemaCA);\n\n        return (\n            _calcRealTCAvailableToRedeem(bucket_, bucketsArray, bucketsPACtps, normalizationFactors),\n            _calcRealTPAvailableToMint(bucket_, tp_, bucketsArray, bucketsPACtps),\n            bucketsPACtps[bucketIndex[bucket_].index]\n        );\n    }\n\n    /**\n     * @notice return current amount of buckets\n     */\n    function getBucketAmount() external view returns (uint256) {\n        return buckets.length;\n    }\n\n    /**\n     * @notice gets all TP prices for each bucket\n     * @return bucketsPACtps All tps prices [PREC]\n     */\n    function getBucketsPACtps() external view returns (uint256[][] memory bucketsPACtps) {\n        return _getBucketsPACtps(buckets);\n    }\n\n    /**\n     * @notice gets all bucket normalization factors\n     * @return normalizationFactors array of normalization factors [PREC]\n     */\n    function getNormalizationFactors() external view returns (uint256[] memory normalizationFactors) {\n        MocOperations[] memory bucketsArray = buckets;\n        return _calcNormalizationFactors(bucketsArray, _getBucketsPACtps(bucketsArray));\n    }\n\n    /**\n     * @notice calc all bucket normalization factors\n     * @param bucketsPACtps_ all tps prices for each bucket [PREC]\n     * @return normalizationFactors array of normalization factors [PREC]\n     */\n    function calcNormalizationFactorsWithPrices(\n        uint256[][] calldata bucketsPACtps_\n    ) external view returns (uint256[] memory normalizationFactors) {\n        return _calcNormalizationFactors(buckets, bucketsPACtps_);\n    }\n\n    /**\n     * @notice gets all buckets combined coverage\n     *  combinedCglb = (Σ cglb(i) * lckACNormalized(i)) / Σ lckACNormalized(i)\n     * @return combinedCglb combined coverage [PREC]\n     */\n    function getCombinedCglb() external view returns (uint256 combinedCglb) {\n        MocOperations[] memory bucketsArray = buckets;\n        uint256[][] memory bucketsPACtps = _getBucketsPACtps(bucketsArray);\n        return _calcCombinedCglb(bucketsArray, bucketsPACtps, _calcNormalizationFactors(bucketsArray, bucketsPACtps));\n    }\n\n    /**\n     * @notice gets all buckets combined coverage\n     *  combinedCglb = (Σ cglb(i) * lckACNormalized(i)) / Σ lckACNormalized(i)\n     * @param bucketsPACtps_ all tps prices for each bucket [PREC]\n     * @return combinedCglb combined coverage [PREC]\n     */\n    function calcCombinedCglbWithPrices(\n        uint256[][] calldata bucketsPACtps_\n    ) external view returns (uint256 combinedCglb) {\n        MocOperations[] memory bucketsArray = buckets;\n        return _calcCombinedCglb(bucketsArray, bucketsPACtps_, _calcNormalizationFactors(bucketsArray, bucketsPACtps_));\n    }\n\n    /**\n     * @notice gets all buckets target coverage adjusted by Ema\n     *  combinedCtargemaCA = (Σ ctargemaCA(i) * lckACNormalized(i)) / Σ lckACNormalized(i)\n     * @return combinedCtargemaCA combined ctargemaCA [PREC]\n     */\n\n    function getCombinedCtargemaCA() public view returns (uint256 combinedCtargemaCA) {\n        MocOperations[] memory bucketsArray = buckets;\n        uint256[][] memory bucketsPACtps = _getBucketsPACtps(bucketsArray);\n        return\n            _calcCombinedCtargemaCA(\n                bucketsArray,\n                bucketsPACtps,\n                _calcNormalizationFactors(bucketsArray, bucketsPACtps)\n            );\n    }\n\n    /**\n     * @notice gets all buckets target coverage adjusted by Ema\n     *  combinedCtargemaCA = (Σ ctargemaCA(i) * lckACNormalized(i)) / Σ lckACNormalized(i)\n     * @param bucketsPACtps_ all tps prices for each bucket [PREC]\n     * @return combinedCtargemaCA combined ctargemaCA [PREC]\n     */\n    function calcCombinedCtargemaCAWithPrices(\n        uint256[][] calldata bucketsPACtps_\n    ) external view returns (uint256 combinedCtargemaCA) {\n        MocOperations[] memory bucketsArray = buckets;\n        return\n            _calcCombinedCtargemaCA(\n                bucketsArray,\n                bucketsPACtps_,\n                _calcNormalizationFactors(bucketsArray, bucketsPACtps_)\n            );\n    }\n\n    /**\n     * @notice gets the real TC available to redeem considering all buckets status\n     * @dev this function only is valid when it is called by a bucket\n     * @param bucket_ bucket that is intended to operate\n     * @return realTCAvailableToRedeem real TC available to redeem [N]\n     */\n    function getRealTCAvailableToRedeem(MocOperations bucket_) external view returns (uint256 realTCAvailableToRedeem) {\n        MocOperations[] memory bucketsArray = buckets;\n        uint256[][] memory bucketsPACtps = _getBucketsPACtps(bucketsArray);\n        return\n            _calcRealTCAvailableToRedeem(\n                bucket_,\n                bucketsArray,\n                bucketsPACtps,\n                _calcNormalizationFactors(bucketsArray, bucketsPACtps)\n            );\n    }\n\n    /**\n     * @notice gets the real TC available to redeem considering all buckets status\n     * @dev this function only is valid when it is called by a bucket\n     * @param bucket_ bucket that is intended to operate\n     * @param bucketsPACtps_ all tps prices for each bucket [PREC]\n     * @return realTCAvailableToRedeem real TC available to redeem [N]\n     */\n    function calcRealTCAvailableToRedeemWithPrices(\n        MocOperations bucket_,\n        uint256[][] calldata bucketsPACtps_\n    ) external view returns (uint256 realTCAvailableToRedeem) {\n        MocOperations[] memory bucketsArray = buckets;\n        return\n            _calcRealTCAvailableToRedeem(\n                bucket_,\n                bucketsArray,\n                bucketsPACtps_,\n                _calcNormalizationFactors(bucketsArray, bucketsPACtps_)\n            );\n    }\n\n    /**\n     * @notice gets the real TP available to mint considering all buckets status\n     * @dev this function only is valid when it is called by a bucket\n     * @param bucket_ bucket that is intended to operate\n     * @param tp_ Pegged Token address\n     * @return realTPAvailableToMint real TP available to mint [N]\n     */\n    function getRealTPAvailableToMint(\n        MocOperations bucket_,\n        address tp_\n    ) external view returns (uint256 realTPAvailableToMint) {\n        MocOperations[] memory bucketsArray = buckets;\n        return _calcRealTPAvailableToMint(bucket_, tp_, bucketsArray, _getBucketsPACtps(bucketsArray));\n    }\n\n    /**\n     * @notice gets the real TP available to mint considering all buckets status\n     * @dev this function only is valid when it is called by a bucket\n     * @param bucket_ bucket that is intended to operate\n     * @param tp_ Pegged Token address\n     * @param bucketsPACtps_ all tps prices for each bucket [PREC]\n     * @return realTPAvailableToMint real TP available to mint [N]\n     */\n    function calcRealTPAvailableToMintWithPrices(\n        MocOperations bucket_,\n        address tp_,\n        uint256[][] calldata bucketsPACtps_\n    ) external view returns (uint256 realTPAvailableToMint) {\n        return _calcRealTPAvailableToMint(bucket_, tp_, buckets, bucketsPACtps_);\n    }\n\n    /**\n     * @notice get the min or max last TP price publication block among all the buckets\n     * @param useMaxLastPublicationBlock_ use the max last publication block to trigger the queue execution\n     * @return lastPublicationBlock the min or max last block where there was a price publication.\n     */\n    function getLastPublicationBlock(\n        bool useMaxLastPublicationBlock_\n    ) external view returns (uint256 lastPublicationBlock) {\n        return _getLastPublicationBlock(buckets, useMaxLastPublicationBlock_);\n    }\n\n    /**\n     * @notice Processes Operations on every bucket's queue\n     * @dev does not revert on Operation failure, throws events according to\n     * the Oper type and result\n     */\n    function execute() external notPaused nonReentrant {\n        MocOperations[] memory bucketsArray = buckets;\n        uint256 bucketsCounter;\n        uint256 totalExecutionFee;\n        uint256 totalPriceUpdatesFee;\n        uint256 remainingOperToExecute = maxOperPerBatch;\n        uint256 blocksSinceLastPublication = block.number -\n            _getLastPublicationBlock(bucketsArray, useMaxLastPublicationBlock);\n\n        while (bucketsCounter < bucketsArray.length && remainingOperToExecute > 0) {\n            // use block.number as bucket index seed not to start always with the same bucket\n            uint256 iBucket = (block.number + bucketsCounter) % bucketsArray.length;\n            (uint256 executionFee, uint256 priceUpdatesFee, uint256 operExecuted) = MocQueue(\n                bucketsArray[iBucket].mocQueue()\n            ).execute(msg.sender, remainingOperToExecute, blocksSinceLastPublication);\n            unchecked {\n                totalExecutionFee += executionFee;\n                totalPriceUpdatesFee += priceUpdatesFee;\n                remainingOperToExecute -= operExecuted;\n                bucketsCounter += 1;\n            }\n        }\n        // Payment priority under constrained balance: execution fees are paid first.\n        // If funds are insufficient after execution fee transfer, the shortfall impacts price update fees.\n        _payCoinbase(totalExecutionFee, coinbaseExecFeeRecipient);\n        _payCoinbase(totalPriceUpdatesFee, priceUpdatesFeeRecipient);\n    }\n\n    /**\n     * @notice Processes Operations on a liquidated bucket\n     * @dev does not revert on Operation failure, throws events according to\n     * the Oper type and result\n     */\n    function executeLiquidatedBucket(MocOperations liquidatedBucket_) external notPaused nonReentrant {\n        if (!bucketIndex[liquidatedBucket_].liquidated) revert BucketNotLiquidated();\n        if (MocQueue(liquidatedBucket_.mocQueue()).isEmpty()) revert BucketEmpty();\n\n        (uint256 totalExecutionFee, uint256 totalPriceUpdatesFee, ) = MocQueue(liquidatedBucket_.mocQueue()).execute(\n            msg.sender,\n            maxOperPerBatch,\n            0 /*blocksSinceLastPublication; allow to execute everything*/\n        );\n\n        // Payment priority under constrained balance: execution fees are paid first.\n        // If funds are insufficient after execution fee transfer, the shortfall impacts price update fees.\n        _payCoinbase(totalExecutionFee, coinbaseExecFeeRecipient);\n        _payCoinbase(totalPriceUpdatesFee, priceUpdatesFeeRecipient);\n    }\n\n    /**\n     * @notice true if some queue has at least one Operation ready to be executed\n     */\n    function readyToExecute() external view returns (bool) {\n        MocOperations[] memory bucketsArray = buckets;\n        uint256 blocksSinceLastPublication = block.number -\n            _getLastPublicationBlock(bucketsArray, useMaxLastPublicationBlock);\n        for (uint256 j = 0; j < bucketsArray.length; j = unchecked_inc(j)) {\n            if (MocQueue(bucketsArray[j].mocQueue()).readyToExecute(blocksSinceLastPublication)) return true;\n        }\n        return false;\n    }\n\n    /**\n     * @notice checks if some bucket requires micro liquidation\n     * @param bucketsPACtps_ all tps prices for each bucket [PREC]\n     * @return true if some bucket requires micro liquidation\n     */\n    function readyToMicroLiquidate(uint256[][] calldata bucketsPACtps_) external view returns (bool) {\n        MocOperations[] memory bucketsArray = buckets;\n        for (uint256 j = 0; j < bucketsArray.length; j = unchecked_inc(j)) {\n            if (isMicroLiquidationAvailableWithPrices(bucketsArray[j], bucketsPACtps_[j])) return true;\n        }\n        return false;\n    }\n\n    /**\n     * @notice checks if some bucket requires liquidation\n     * @param bucketsPACtps_ all tps prices for each bucket [PREC]\n     * @return true if some bucket requires liquidation\n     */\n    function readyToLiquidate(uint256[][] calldata bucketsPACtps_) external view returns (bool) {\n        MocOperations[] memory bucketsArray = buckets;\n        for (uint256 j = 0; j < bucketsArray.length; j = unchecked_inc(j)) {\n            if (isLiquidationAvailableWithPrices(bucketsArray[j], bucketsPACtps_[j])) return true;\n        }\n        return false;\n    }\n\n    // ------- Only Authorized Functions -------\n\n    /**\n     * @notice sets maximum amount of operations per execution batch\n     * @param maxOperPerBatch_ maximum amount of operations allowed on a batch to avoid going over\n     * the block gas limit\n     */\n    function setMaxOperPerBatch(uint256 maxOperPerBatch_) external onlyAuthorizedChanger {\n        maxOperPerBatch = maxOperPerBatch_;\n    }\n\n    /**\n     * @notice switches the way that price providers trigger the queue execution using the last publication block\n     * false: use the minimum, so operations enqueued before the oldest price are executed. New operations\n     *  have to wait until all the prices are updated\n     * true: use the maximum, so operations enqueued before the newest price are executed. New operations\n     *  have to wait until only one price is updated\n     * @param useMaxLastPublicationBlock_ new way to trigger the queue execution using the last publication block\n     */\n    function setUseMaxLastPublicationBlock(bool useMaxLastPublicationBlock_) external onlyAuthorizedChanger {\n        useMaxLastPublicationBlock = useMaxLastPublicationBlock_;\n    }\n\n    /**\n     * @notice sets the address of the coinbase execution fee recipient\n     * @param coinbaseExecFeeRecipient_ address of the coinbase execution fee recipient\n     */\n    function setCoinbaseExecFeeRecipient(address payable coinbaseExecFeeRecipient_) external onlyAuthorizedChanger {\n        coinbaseExecFeeRecipient = coinbaseExecFeeRecipient_;\n    }\n\n    /**\n     * @notice sets the address of the price update fee recipient\n     * @param priceUpdatesFeeRecipient_ address of the price update fee recipient\n     */\n    function setPriceUpdatesFeeRecipient(address priceUpdatesFeeRecipient_) external onlyAuthorizedChanger {\n        priceUpdatesFeeRecipient = priceUpdatesFeeRecipient_;\n    }\n\n    // @notice used to receive executions fee payment\n    receive() external payable {}\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/proxy/transparent/TransparentUpgradeableProxy.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev Interface for {TransparentUpgradeableProxy}. In order to implement transparency, {TransparentUpgradeableProxy}\n * does not implement this interface directly, and some of its functions are implemented by an internal dispatch\n * mechanism. The compiler is unaware that these functions are implemented by {TransparentUpgradeableProxy} and will not\n * include them in the ABI so this interface must be used to interact with it.\n */\ninterface ITransparentUpgradeableProxy is IERC1967 {\n    function admin() external view returns (address);\n\n    function implementation() external view returns (address);\n\n    function changeAdmin(address) external;\n\n    function upgradeTo(address) external;\n\n    function upgradeToAndCall(address, bytes memory) external payable;\n}\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n *\n * NOTE: The real interface of this proxy is that defined in `ITransparentUpgradeableProxy`. This contract does not\n * inherit from that interface, and instead the admin functions are implicitly implemented using a custom dispatch\n * mechanism in `_fallback`. Consequently, the compiler will not produce an ABI for this contract. This is necessary to\n * fully implement transparency without decoding reverts caused by selector clashes between the proxy and the\n * implementation.\n *\n * WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the compiler\n * will not check that there are no selector conflicts, due to the note above. A selector clash between any new function\n * and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This could\n * render the admin operations inaccessible, which could prevent upgradeability. Transparency may also be compromised.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n    /**\n     * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n     * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n     */\n    constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n        _changeAdmin(admin_);\n    }\n\n    /**\n     * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n     *\n     * CAUTION: This modifier is deprecated, as it could cause issues if the modified function has arguments, and the\n     * implementation provides a function with the same selector.\n     */\n    modifier ifAdmin() {\n        if (msg.sender == _getAdmin()) {\n            _;\n        } else {\n            _fallback();\n        }\n    }\n\n    /**\n     * @dev If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior\n     */\n    function _fallback() internal virtual override {\n        if (msg.sender == _getAdmin()) {\n            bytes memory ret;\n            bytes4 selector = msg.sig;\n            if (selector == ITransparentUpgradeableProxy.upgradeTo.selector) {\n                ret = _dispatchUpgradeTo();\n            } else if (selector == ITransparentUpgradeableProxy.upgradeToAndCall.selector) {\n                ret = _dispatchUpgradeToAndCall();\n            } else if (selector == ITransparentUpgradeableProxy.changeAdmin.selector) {\n                ret = _dispatchChangeAdmin();\n            } else if (selector == ITransparentUpgradeableProxy.admin.selector) {\n                ret = _dispatchAdmin();\n            } else if (selector == ITransparentUpgradeableProxy.implementation.selector) {\n                ret = _dispatchImplementation();\n            } else {\n                revert(\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n            }\n            assembly {\n                return(add(ret, 0x20), mload(ret))\n            }\n        } else {\n            super._fallback();\n        }\n    }\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n     */\n    function _dispatchAdmin() private returns (bytes memory) {\n        _requireZeroValue();\n\n        address admin = _getAdmin();\n        return abi.encode(admin);\n    }\n\n    /**\n     * @dev Returns the current implementation.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n     */\n    function _dispatchImplementation() private returns (bytes memory) {\n        _requireZeroValue();\n\n        address implementation = _implementation();\n        return abi.encode(implementation);\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     */\n    function _dispatchChangeAdmin() private returns (bytes memory) {\n        _requireZeroValue();\n\n        address newAdmin = abi.decode(msg.data[4:], (address));\n        _changeAdmin(newAdmin);\n\n        return \"\";\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy.\n     */\n    function _dispatchUpgradeTo() private returns (bytes memory) {\n        _requireZeroValue();\n\n        address newImplementation = abi.decode(msg.data[4:], (address));\n        _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n\n        return \"\";\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n     * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n     * proxied contract.\n     */\n    function _dispatchUpgradeToAndCall() private returns (bytes memory) {\n        (address newImplementation, bytes memory data) = abi.decode(msg.data[4:], (address, bytes));\n        _upgradeToAndCall(newImplementation, data, true);\n\n        return \"\";\n    }\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * CAUTION: This function is deprecated. Use {ERC1967Upgrade-_getAdmin} instead.\n     */\n    function _admin() internal view virtual returns (address) {\n        return _getAdmin();\n    }\n\n    /**\n     * @dev To keep this contract fully transparent, all `ifAdmin` functions must be payable. This helper is here to\n     * emulate some proxy functions being non-payable while still allowing value to pass through.\n     */\n    function _requireZeroValue() private {\n        require(msg.value == 0);\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/access/Ownable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/utils/Context.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/auxiliary/CommissionSplitterBase.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { Governed } from \"../governance/Governed.sol\";\nimport { UUPSUpgradeable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/**\n  @dev Contract that split his balance between two addresses based on a\n  proportion defined by Governance.\n */\nabstract contract CommissionSplitterBase is Governed, UUPSUpgradeable {\n    // ------- Events -------\n\n    event SplitExecuted(\n        uint256 acTokenPctToRecipient1_,\n        uint256 acTokenPctToRecipient2_,\n        uint256 feeTokenPctToRecipient1_,\n        uint256 feeTokenPctToRecipient2_\n    );\n\n    // ------- Storage -------\n\n    // fee token\n    IERC20 public feeToken;\n\n    // address who receives acTokenPctToRecipient1\n    address public acTokenAddressRecipient1;\n    // address who receives the rest of the commissions (100% - acTokenPctToRecipient1)\n    address public acTokenAddressRecipient2;\n    // percentage of the acToken balance to send to acTokenAddressRecipient1 [PREC]\n    uint256 public acTokenPctToRecipient1;\n\n    // address who receives feeTokenPctToRecipient1\n    address public feeTokenAddressRecipient1;\n    // address who receives the rest of the commissions (100% - feeTokenPctToRecipient1)\n    address public feeTokenAddressRecipient2;\n    // percentage of the feeToken balance to send to acTokenAddressRecipient1 [PREC]\n    uint256 public feeTokenPctToRecipient1;\n\n    /**\n     * @notice contract initializer\n     * @param governorAddress_ governor address\n     * @param feeToken_ fee token contract\n     * @param acTokenAddressRecipient1_ address who receives acTokenPctToRecipient1\n     * @param acTokenAddressRecipient2_ address who receives (100% - acTokenPctToRecipient1)\n     * @param acTokenPctToRecipient1_ percentage of the acToken balance to send to acTokenAddressRecipient1 [PREC]\n     * @param feeTokenAddressRecipient1_ address who receives feeTokenPctToRecipient1\n     * @param feeTokenAddressRecipient2_ address who receives (100% - feeTokenPctToRecipient1)\n     * @param feeTokenPctToRecipient1_ percentage of the feeToken balance to send to acTokenAddressRecipient1 [PREC]\n     */\n    // slither-disable missing-zero-check\n    function __CommissionSplitter_init(\n        address governorAddress_,\n        IERC20 feeToken_,\n        address acTokenAddressRecipient1_,\n        address acTokenAddressRecipient2_,\n        uint256 acTokenPctToRecipient1_,\n        address feeTokenAddressRecipient1_,\n        address feeTokenAddressRecipient2_,\n        uint256 feeTokenPctToRecipient1_\n    ) internal onlyInitializing {\n        if (acTokenPctToRecipient1_ > PRECISION) revert InvalidValue();\n        if (feeTokenPctToRecipient1_ > PRECISION) revert InvalidValue();\n        __UUPSUpgradeable_init();\n        __Governed_init(governorAddress_);\n\n        feeToken = feeToken_;\n        acTokenAddressRecipient1 = acTokenAddressRecipient1_;\n        acTokenAddressRecipient2 = acTokenAddressRecipient2_;\n        acTokenPctToRecipient1 = acTokenPctToRecipient1_;\n        feeTokenAddressRecipient1 = feeTokenAddressRecipient1_;\n        feeTokenAddressRecipient2 = feeTokenAddressRecipient2_;\n        feeTokenPctToRecipient1 = feeTokenPctToRecipient1_;\n    }\n\n    // ------- Internal abstract Functions -------\n\n    /**\n     * @notice get the AC balance of the contract\n     * @dev this function must be overridden by the AC implementation\n     * @return balance of the contract\n     */\n    function _acBalanceOfSelf() internal view virtual returns (uint256);\n\n    /**\n     * @notice transfers AC to a recipient\n     * @dev this function must be overridden by the AC implementation\n     *  and revert if transfer fails.\n     * @param recipient_ recipient address\n     * @param amount_ amount to transfer\n     */\n    function _acTransfer(address recipient_, uint256 amount_) internal virtual;\n\n    // ------- External Functions -------\n\n    /**\n     * @notice splits all the acToken and feeToken balances to the recipients addresses\n     */\n    function split() external {\n        uint256 acTokenAmountToRecipient1;\n        uint256 acTokenAmountToRecipient2;\n        uint256 feeTokenAmountToRecipient1;\n        uint256 feeTokenAmountToRecipient2;\n\n        // splits collateral asset\n        uint256 acTokenBalance = _acBalanceOfSelf();\n        if (acTokenBalance > 0) {\n            acTokenAmountToRecipient1 = _mulPrec(acTokenBalance, acTokenPctToRecipient1);\n            acTokenAmountToRecipient2 = acTokenBalance - acTokenAmountToRecipient1;\n            _acTransfer(acTokenAddressRecipient1, acTokenAmountToRecipient1);\n            _acTransfer(acTokenAddressRecipient2, acTokenAmountToRecipient2);\n        }\n\n        // splits fee token\n        uint256 feeTokenBalance = feeToken.balanceOf(address(this));\n        if (feeTokenBalance > 0) {\n            feeTokenAmountToRecipient1 = _mulPrec(feeTokenBalance, feeTokenPctToRecipient1);\n            feeTokenAmountToRecipient2 = feeTokenBalance - feeTokenAmountToRecipient1;\n            SafeERC20.safeTransfer(feeToken, feeTokenAddressRecipient1, feeTokenAmountToRecipient1);\n            SafeERC20.safeTransfer(feeToken, feeTokenAddressRecipient2, feeTokenAmountToRecipient2);\n        }\n\n        emit SplitExecuted(\n            acTokenAmountToRecipient1,\n            acTokenAmountToRecipient2,\n            feeTokenAmountToRecipient1,\n            feeTokenAmountToRecipient2\n        );\n    }\n\n    // ------- Only Authorized Changer Functions -------\n\n    /** @notice sets new fee token\n     * @param newFeeToken_ new fee token contract\n     */\n    function setFeeToken(IERC20 newFeeToken_) external onlyAuthorizedChanger {\n        feeToken = newFeeToken_;\n    }\n\n    /** @notice sets new recipient1 for AC token\n     * @param acTokenAddressRecipient1_ new recipient1 address\n     */\n    function setAcTokenAddressRecipient1(address acTokenAddressRecipient1_) external onlyAuthorizedChanger {\n        acTokenAddressRecipient1 = acTokenAddressRecipient1_;\n    }\n\n    /** @notice sets new recipient2 for AC token\n     * @param acTokenAddressRecipient2_ new recipient1 address\n     */\n    function setAcTokenAddressRecipient2(address acTokenAddressRecipient2_) external onlyAuthorizedChanger {\n        acTokenAddressRecipient2 = acTokenAddressRecipient2_;\n    }\n\n    /** @notice sets new percentage of AC token for recipient1\n     * @param acTokenPctToRecipient1_ new percentage for recipient1 [PREC]\n     */\n    function setAcTokenPctToRecipient1(uint256 acTokenPctToRecipient1_) external onlyAuthorizedChanger {\n        if (acTokenPctToRecipient1_ > PRECISION) revert InvalidValue();\n        acTokenPctToRecipient1 = acTokenPctToRecipient1_;\n    }\n\n    /** @notice sets new recipient1 for fee token\n     * @param feeTokenAddressRecipient1_ new recipient1 address\n     */\n    function setFeeTokenAddressRecipient1(address feeTokenAddressRecipient1_) external onlyAuthorizedChanger {\n        feeTokenAddressRecipient1 = feeTokenAddressRecipient1_;\n    }\n\n    /** @notice sets new recipient2 for fee token\n     * @param feeTokenAddressRecipient2_ new recipient2 address\n     */\n    function setFeeTokenAddressRecipient2(address feeTokenAddressRecipient2_) external onlyAuthorizedChanger {\n        feeTokenAddressRecipient2 = feeTokenAddressRecipient2_;\n    }\n\n    /** @notice sets new percentage of fee token for recipient1\n     * @param feeTokenPctToRecipient1_ new percentage for recipient1 [PREC]\n     */\n    function setFeeTokenPctToRecipient1(uint256 feeTokenPctToRecipient1_) external onlyAuthorizedChanger {\n        if (feeTokenPctToRecipient1_ > PRECISION) revert InvalidValue();\n        feeTokenPctToRecipient1 = feeTokenPctToRecipient1_;\n    }\n\n    /**\n     * @inheritdoc UUPSUpgradeable\n     * @dev checks that the changer that will do the upgrade is currently authorized by governance to makes\n     * changes within the system\n     * @param newImplementation new implementation contract address(not used)\n     */\n    function _authorizeUpgrade(address newImplementation) internal override onlyAuthorizedChanger {}\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/proxy/utils/UUPSUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/draft-IERC1822Upgradeable.sol\";\nimport \"../ERC1967/ERC1967UpgradeUpgradeable.sol\";\nimport \"./Initializable.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * _Available since v4.1._\n */\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\n    function __UUPSUpgradeable_init() internal onlyInitializing {\n    }\n\n    function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\n    }\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n    address private immutable __self = address(this);\n\n    /**\n     * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n     * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n     * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n     * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n     * fail.\n     */\n    modifier onlyProxy() {\n        require(address(this) != __self, \"Function must be called through delegatecall\");\n        require(_getImplementation() == __self, \"Function must be called through active proxy\");\n        _;\n    }\n\n    /**\n     * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n     * callable on the implementing contract but not through proxies.\n     */\n    modifier notDelegated() {\n        require(address(this) == __self, \"UUPSUpgradeable: must not be called through delegatecall\");\n        _;\n    }\n\n    /**\n     * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n     * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n     */\n    function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\n        return _IMPLEMENTATION_SLOT;\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy to `newImplementation`.\n     *\n     * Calls {_authorizeUpgrade}.\n     *\n     * Emits an {Upgraded} event.\n     *\n     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n     */\n    function upgradeTo(address newImplementation) public virtual onlyProxy {\n        _authorizeUpgrade(newImplementation);\n        _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n     * encoded in `data`.\n     *\n     * Calls {_authorizeUpgrade}.\n     *\n     * Emits an {Upgraded} event.\n     *\n     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n     */\n    function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\n        _authorizeUpgrade(newImplementation);\n        _upgradeToAndCallUUPS(newImplementation, data, true);\n    }\n\n    /**\n     * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n     * {upgradeTo} and {upgradeToAndCall}.\n     *\n     * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n     *\n     * ```solidity\n     * function _authorizeUpgrade(address) internal override onlyOwner {}\n     * ```\n     */\n    function _authorizeUpgrade(address newImplementation) internal virtual;\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/v3/TaskExecuteMicroLiquidationV3.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../ITask.sol\";\nimport { MocMultiCollateralGuard } from \"@moc/moc-main/contracts/multiCollateral/MocMultiCollateralGuard.sol\";\nimport { MocOperations } from \"@moc/moc-main/contracts/core/MocOperations.sol\";\n\n/**\n * @title TaskExecuteMicroLiquidationV3\n * @notice This contract implements a task that evaluates if micro-liquidation is needed and runs it if so.\n */\ncontract TaskExecuteMicroLiquidationV3 is ITask {\n    error TaskNotAvailable();\n\n    MocMultiCollateralGuard public immutable mocMultiCollateralGuard;\n    MocOperations public immutable bucket;\n\n    /**\n     * @notice Constructor\n     * @param mocMultiCollateralGuard_ The address of the MocMultiCollateralGuard contract.\n     * @param bucket_ The address of the MocOperations contract.\n     */\n    constructor(address payable mocMultiCollateralGuard_, address bucket_) {\n        mocMultiCollateralGuard = MocMultiCollateralGuard(mocMultiCollateralGuard_);\n        bucket = MocOperations(bucket_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() external view returns (bool) {\n        MocMultiCollateralGuard mocMC = mocMultiCollateralGuard;\n        if (mocMC.paused()) return false;\n        return mocMC.isMicroLiquidationAvailable(bucket);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        mocMultiCollateralGuard.execMicroLiquidation(bucket);\n    }\n}\n"},{"file_path":"project/contracts/TokenMigrator.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\n\n/**\n * @title TokenMigrator\n * @notice Migrates balances from a legacy ERC20 token to a new ERC20 token.\n * This contract holds the supply of new tokens available for migration.\n * To migrate, token holders must approve this contract to transfer their full legacy token balance.\n * During migration, legacy tokens are transferred from the holder to this contract, where they remain\n * indefinitely, and new tokens are sent to the holder according to the configured migration rate.\n */\ncontract TokenMigrator {\n    using SafeERC20 for IERC20;\n\n    error InsufficientLegacyTokenBalance();\n    error InvalidMigrationRate();\n\n    IERC20 public immutable legacyToken;\n    IERC20 public immutable newToken;\n    uint256 public immutable migrationRate;\n    uint256 public _totalMigrated;\n\n    uint256 public constant MIGRATION_RATE_PRECISION = 1e18;\n\n    /**\n     * @notice Emitted when tokens are migrated.\n     * @param sender_ The caller that triggered the migration.\n     * @param user_ The holder whose tokens were migrated.\n     * @param legacyAmount_ The legacy token amount migrated.\n     * @param newAmount_ The new token amount sent to the holder.\n     */\n    event TokenMigrated(address indexed sender_, address indexed user_, uint256 legacyAmount_, uint256 newAmount_);\n\n    /**\n     * @param legacyToken_ The legacy token address.\n     * @param newToken_ The new token address.\n     * @param migrationRate_ The amount of new tokens sent per legacy token, scaled by `MIGRATION_RATE_PRECISION`.\n     */\n    constructor(address legacyToken_, address newToken_, uint256 migrationRate_) {\n        if (migrationRate_ == 0) revert InvalidMigrationRate();\n        legacyToken = IERC20(legacyToken_);\n        newToken = IERC20(newToken_);\n        migrationRate = migrationRate_;\n    }\n\n    /**\n     * @notice Migrates `user_`'s full legacy token balance to the new token using the configured migration rate.\n     * `user_` must approve this contract to transfer their legacy tokens before this function is called.\n     * @param user_ The holder whose tokens are migrated.\n     */\n    function _migrateToken(address user_) internal {\n        uint256 legacyAmount = legacyToken.balanceOf(user_);\n        if (legacyAmount == 0) revert InsufficientLegacyTokenBalance();\n        uint256 newAmount = Math.mulDiv(legacyAmount, migrationRate, MIGRATION_RATE_PRECISION);\n        _totalMigrated += legacyAmount;\n        legacyToken.safeTransferFrom(user_, address(this), legacyAmount);\n        newToken.safeTransfer(user_, newAmount);\n        emit TokenMigrated(msg.sender, user_, legacyAmount, newAmount);\n    }\n\n    /**\n     * @notice Migrates the caller's full legacy token balance to the new token using the configured migration rate.\n     * The caller must approve this contract to transfer their legacy tokens before calling this function.\n     */\n    function migrateToken() external {\n        _migrateToken(msg.sender);\n    }\n\n    /**\n     * @notice Migrates `user_`'s full legacy token balance to the new token using the configured migration rate.\n     * `user_` must approve this contract to transfer their legacy tokens before this function is called.\n     * @param user_ The holder whose tokens are migrated.\n     */\n    function migrateTokenFrom(address user_) external {\n        _migrateToken(user_);\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/utils/StorageSlot.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\n * _Available since v4.9 for `string`, `bytes`._\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n}\n"},{"file_path":"npm/price-oracle-interfaces@0.1.0/contracts/PriceProviderDocUsd.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.24;\n\nimport \"./interfaces/IPriceProvider.sol\";\nimport \"./interfaces/IMocState.sol\";\nimport \"./interfaces/ICoinPairPrice.sol\";\nimport \"./DocPriceLib.sol\";\n\n/// @title PriceProviderDocUsd\n/// @notice Exposes MoC's DOC/USD price through IPriceProvider with 18 decimals.\n/// @dev DOC/USD is capped at 1e18 (senior claim).\ncontract PriceProviderDocUsd is IPriceProvider {\n  IMocState public immutable mocState;\n  ICoinPairPrice public immutable btcPriceProvider;\n\n  constructor(IMocState _mocState) {\n    require(address(_mocState) != address(0), \"mocState address is zero\");\n    mocState = _mocState;\n    btcPriceProvider = ICoinPairPrice(_mocState.getBtcPriceProvider());\n  }\n\n  function peek() external view override returns (bytes32, bool) {\n    (bytes32 btcPriceInUsdBytes, bool btcPriceIsValid) = btcPriceProvider.peek();\n    uint256 btcPriceInUsd = uint256(btcPriceInUsdBytes);\n    uint256 docPriceInUsd = DocPriceLib.docUsdPriceSafe(mocState, btcPriceInUsd);\n\n    bool overallValid = btcPriceIsValid && btcPriceInUsd != 0 && docPriceInUsd != 0;\n    return (bytes32(docPriceInUsd), overallValid);\n  }\n\n  function getLastPublicationBlock() external view override returns (uint256) {\n    return btcPriceProvider.getLastPublicationBlock();\n  }\n}\n"},{"file_path":"project/contracts/providers/WrapperPriceProvider.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport \"moc-main-latest/contracts/interfaces/IPriceProvider.sol\";\n\n/// @title Price Provider\n/// @notice Returns a price and reports the current block as last publication.\ncontract WrapperPriceProvider is IPriceProvider {\n    IPriceProvider public underlyingPriceProvider;\n\n    constructor(IPriceProvider _priceProvider) {\n        underlyingPriceProvider = _priceProvider;\n    }\n\n    /// @dev Returns same value as the underlying price provider.\n    function peek() external view override returns (bytes32, bool) {\n        return underlyingPriceProvider.peek();\n    }\n\n    /// @dev Reports the *current* block to look fresh to age checkers.\n    function getLastPublicationBlock() external view override returns (uint256) {\n        return block.number;\n    }\n}\n"},{"file_path":"project/contracts/changers/PauserSplitChanger/PauserSplitChanger.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IChangeContract } from \"moc-main-latest/contracts/interfaces/IChangeContract.sol\";\nimport { MocMultiCollateralGuard } from \"moc-main-latest/contracts/multiCollateral/MocMultiCollateralGuard.sol\";\nimport { MocOperations } from \"moc-main-latest/contracts/core/MocOperations.sol\";\nimport { MocQueue } from \"moc-main-latest/contracts/queue/MocQueue.sol\";\nimport { MocVendors } from \"moc-main-latest/contracts/vendors/MocVendors.sol\";\n\n/**\n * @title PauserSplitChanger\n * @notice Sets a new pauser on MocMultiCollateralGuard, all registered buckets, their queues and MocVendors\n */\ncontract PauserSplitChanger is IChangeContract {\n    MocMultiCollateralGuard public immutable mocMultiCollateralGuard;\n    address public immutable newPauser;\n\n    constructor(MocMultiCollateralGuard mocMultiCollateralGuard_, address newPauser_) {\n        mocMultiCollateralGuard = mocMultiCollateralGuard_;\n        newPauser = newPauser_;\n    }\n\n    function execute() external {\n        mocMultiCollateralGuard.setPauser(newPauser);\n\n        MocVendors mocVendors = mocMultiCollateralGuard.buckets(0).mocVendors();\n        mocVendors.setPauser(newPauser);\n        mocVendors.setVendorsGuardianAddress(newPauser);\n\n        uint256 bucketAmount = mocMultiCollateralGuard.getBucketAmount();\n        for (uint256 i = 0; i < bucketAmount; i++) {\n            MocOperations bucket = mocMultiCollateralGuard.buckets(i);\n            bucket.setPauser(newPauser);\n            MocQueue(bucket.mocQueue()).setPauser(newPauser);\n        }\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/utils/StringsUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n    bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n    uint8 private constant _ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            uint256 length = MathUpgradeable.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toString(int256 value) internal pure returns (string memory) {\n        return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMathUpgradeable.abs(value))));\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, MathUpgradeable.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"},{"file_path":"npm/price-oracle-interfaces@0.1.0/contracts/PriceProviderDocRbtc.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.24;\n\nimport \"./interfaces/IPriceProvider.sol\";\nimport \"./interfaces/IMocState.sol\";\nimport \"./interfaces/ICoinPairPrice.sol\";\nimport \"./DocPriceLib.sol\";\n\n/// @title PriceProviderDocRbtc\n/// @notice Exposes MoC's DOC/RBTC price through IPriceProvider with 18 decimals.\n/// @dev DOC/RBTC is capped at USD/BTC (inverse of BTC/USD) to preserve the 1 USD DOC peg upper bound.\ncontract PriceProviderDocRbtc is IPriceProvider {\n  IMocState public immutable mocState;\n  ICoinPairPrice public immutable btcPriceProvider;\n\n  constructor(IMocState _mocState) {\n    require(address(_mocState) != address(0), \"mocState address is zero\");\n    mocState = _mocState;\n    btcPriceProvider = ICoinPairPrice(_mocState.getBtcPriceProvider());\n  }\n\n  function peek() external view override returns (bytes32, bool) {\n    (bytes32 btcPriceInUsdBytes, bool btcPriceIsValid) = btcPriceProvider.peek();\n    uint256 btcPriceInUsd = uint256(btcPriceInUsdBytes);\n    uint256 docPriceInRbtc = DocPriceLib.docRbtcPriceSafe(mocState, btcPriceInUsd);\n\n    bool overallValid = btcPriceIsValid && btcPriceInUsd != 0 && docPriceInRbtc != 0;\n    return (bytes32(docPriceInRbtc), overallValid);\n  }\n\n  function getLastPublicationBlock() external view override returns (uint256) {\n    return btcPriceProvider.getLastPublicationBlock();\n  }\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/access/IAccessControlEnumerableUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n    /**\n     * @dev Returns one of the accounts that have `role`. `index` must be a\n     * value between 0 and {getRoleMemberCount}, non-inclusive.\n     *\n     * Role bearers are not sorted in any particular way, and their ordering may\n     * change at any point.\n     *\n     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n     * you perform all queries on the same block. See the following\n     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n     * for more information.\n     */\n    function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n    /**\n     * @dev Returns the number of accounts that have `role`. Can be used\n     * together with {getRoleMember} to enumerate all bearers of a role.\n     */\n    function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/governance/InterimGovernor.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IGovernor } from \"../interfaces/IGovernor.sol\";\nimport { IChangeContract } from \"../interfaces/IChangeContract.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title InterimGovernor\n * @notice Basic governor that handles its governed contracts changes\n *  when are done by this contract owner.\n *  It is used to set parameters during the deployment and then the transfer\n *  to the real governor must be done\n */\ncontract InterimGovernor is IGovernor, Ownable {\n    /**\n     * @notice Function to be called to make the changes in changeContract\n     * @param changeContract_ Address of the contract that will execute the changes\n     */\n    function executeChange(IChangeContract changeContract_) external onlyOwner {\n        changeContract_.execute();\n    }\n\n    /**\n     * @notice Only the owner can call protected functions on the Governed contract\n     * @param caller_ Address of the caller of the protected function\n     */\n    function isAuthorizedChanger(address caller_) external view override returns (bool) {\n        return caller_ == owner();\n    }\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/v3/TaskExecuteLiquidationV3.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../ITask.sol\";\nimport { MocMultiCollateralGuard } from \"@moc/moc-main/contracts/multiCollateral/MocMultiCollateralGuard.sol\";\nimport { MocOperations } from \"@moc/moc-main/contracts/core/MocOperations.sol\";\n\n/**\n * @title TaskEvalLiquidationV3\n * @notice This contract implements a task that evaluates if liquidation is needed and runs it if so.\n */\ncontract TaskExecuteLiquidationV3 is ITask {\n    error TaskNotAvailable();\n\n    MocMultiCollateralGuard public immutable mocMultiCollateralGuard;\n    MocOperations public immutable bucket;\n    /**\n     * @notice Constructor\n     * @param mocMultiCollateralGuard_ The address of the MocMultiCollateralGuard contract.\n     * @param bucket_ The address of the MocOperations contract.\n     */\n    constructor(address payable mocMultiCollateralGuard_, address bucket_) {\n        mocMultiCollateralGuard = MocMultiCollateralGuard(mocMultiCollateralGuard_);\n        bucket = MocOperations(bucket_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() external view returns (bool) {\n        MocMultiCollateralGuard mocMC = mocMultiCollateralGuard;\n        if (mocMC.paused()) return false;\n        return mocMC.isLiquidationAvailable(bucket);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        mocMultiCollateralGuard.execLiquidation(bucket);\n    }\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/utils/MocHelper.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nabstract contract MocHelper {\n    error InvalidAddress();\n    error InvalidValue();\n    // Constants may not be used in child contracts and that is fine as they are\n    // not using any space in storage, so we disable the check\n    // slither-disable-next-line unused-state\n    uint256 internal constant PRECISION = 10 ** 18;\n    // slither-disable-next-line unused-state\n    uint256 internal constant ONE = 10 ** 18;\n    // slither-disable-next-line unused-state\n    uint256 internal constant UINT256_MAX = ~uint256(0);\n\n    // Saves gas\n    // https://github.com/KadenZipfel/gas-optimizations/blob/main/gas-saving-patterns/unchecked-arithmetic.md\n    function unchecked_inc(uint256 i) internal pure returns (uint256) {\n        unchecked {\n            return i + 1;\n        }\n    }\n\n    /**\n     * @notice add precision and div two number\n     * @param a_ numerator\n     * @param b_ denominator\n     * @return `a_` * PRECISION / `b_`\n     */\n    function _divPrec(uint256 a_, uint256 b_) internal pure returns (uint256) {\n        return (a_ * PRECISION) / b_;\n    }\n\n    /**\n     * @notice multiply two number and remove precision\n     * @param a_ term 1\n     * @param b_ term 2\n     * @return `a_` * `b_` / PRECISION\n     */\n    function _mulPrec(uint256 a_, uint256 b_) internal pure returns (uint256) {\n        return (a_ * b_) / PRECISION;\n    }\n\n    /**\n     * @notice reverts if value if less than PRECISION ONE\n     * @param value_ value to check [PREC]\n     */\n    function _checkLessThanOne(uint256 value_) internal pure {\n        if (value_ >= ONE) revert InvalidValue();\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/utils/AddressUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/interfaces/IWrapper.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IWrapper is IERC20 {\n    /// @dev `msg.value` of coinbase sent to this contract grants caller account a matching increase\n    /// in Wrapper token balance.\n    function deposit() external payable;\n\n    /// @dev Burn `value` Wrapper token from caller account and withdraw matching coinbase to the same.\n    function withdraw(uint256 value) external;\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/core/MocOperations.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocCore } from \"./MocCore.sol\";\nimport { MocQueue } from \"../queue/MocQueue.sol\";\nimport { MocQueueExecFees } from \"../queue/MocQueueExecFees.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\n\n/**\n * @title MocOperations\n * @notice All the Moc Protocol operations are grouped in this contract\n */\nabstract contract MocOperations is MocCore {\n    // ------- Custom Errors -------\n    error OnlyQueue();\n\n    // ------- Modifiers -------\n    modifier onlyMocQueue() {\n        if (msg.sender != mocQueue) revert OnlyQueue();\n        _;\n    }\n\n    // ----------------- Abstract Functions ---------------------\n\n    /**\n     * @notice get the amount of coinbase sent to be used as execution fee\n     * @dev this function must be overridden by the AC implementation\n     * @param qACTotal_ provided Collateral Asset amount\n     * @param operType_ Operation Type\n     * @return qACmax maximum amount of Collateral Asset that can be spent on the Operation\n     * @return execFee amount of coinbase to be payed as execution Fee\n     */\n    function _getExecFeeSent(\n        uint256 qACTotal_,\n        MocQueueExecFees.OperType operType_\n    ) internal virtual returns (uint256 qACmax, uint256 execFee);\n\n    /**\n     * @notice while executing a pending Operation, if it fails we need to unlock user's funds\n     * @param owner_ funds owner, address to be returned to\n     * @param qACToUnlock_ AC amount to be unlocked\n     */\n    function unlockACInPending(address owner_, uint256 qACToUnlock_) external onlyMocQueue {\n        unchecked {\n            qACLockedInPending -= qACToUnlock_;\n        }\n        acTransfer(owner_, qACToUnlock_);\n    }\n\n    // ----------------- Internal Functions ---------------------\n\n    /**\n     * @notice sends the fee to MocMultiCollateralGuard for later execution\n     * @param qACTotal_ provided Collateral Asset amount\n     * @param operType_ Operation Type\n     * @return qACmax maximum amount of Collateral Asset that can be spent on the Operation\n     */\n    function _transferExecFee(\n        uint256 qACTotal_,\n        MocQueueExecFees.OperType operType_\n    ) internal returns (uint256 qACmax) {\n        uint256 execFee;\n        (qACmax, execFee) = _getExecFeeSent(qACTotal_, operType_);\n        (bool success, ) = payable(address(_getMocMultiCollateralGuard())).call{ value: execFee }(\"\");\n        if (!success) revert TransferFailed();\n    }\n\n    /**\n     * @notice while registering a pending Operation, we need to lock user's funds until it's executed\n     * @param qACToLock_ AC amount to be locked\n     */\n    function _lockACInPending(uint256 qACToLock_) internal virtual {\n        qACLockedInPending += qACToLock_;\n    }\n\n    /**\n     * @notice while registering a pending Operation, we need to lock user's tokens until it's executed\n     * @param qTCToLock_ TC amount to be locked\n     */\n    function _lockTCInPending(uint256 qTCToLock_) internal {\n        SafeERC20Upgradeable.safeTransferFrom(tcToken, msg.sender, address(this), qTCToLock_);\n    }\n\n    /**\n     * @notice while registering a pending Operation, we need to lock user's tokens until it's executed\n     * @dev Validates that the TP token is a registered Pegged Token before locking to prevent\n     *  attacker-controlled tokens from entering the queue.\n     * @param tpToken TP token to lock\n     * @param qTPToLock_ TP amount to be locked\n     */\n    function _lockTPInPending(IERC20Upgradeable tpToken, uint256 qTPToLock_) internal {\n        // Reverts with InvalidAddress if `tpToken` is not a registered Pegged Token\n        _tpi(address(tpToken));\n        SafeERC20Upgradeable.safeTransferFrom(tpToken, msg.sender, address(this), qTPToLock_);\n    }\n\n    /**\n     * @notice caller sends Collateral Asset and recipient receives Collateral Token\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not\n     *   Requires prior sender approval of Collateral Asset to this contract\n     * @param qTC_ amount of Collateral Token to mint\n     * @param qACmax_ maximum amount of Collateral Asset that can be spent\n     * @param recipient_ address who receives the Collateral Token\n     * @param vendor_ address who receives a markup\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function _mintTCtoViaVendor(\n        uint256 qTC_,\n        uint256 qACmax_,\n        address recipient_,\n        address vendor_\n    ) internal notLiquidated notPaused checkRecipient(msg.sender, recipient_) returns (uint256 operId) {\n        uint256 qACmax = _transferExecFee(qACmax_, MocQueueExecFees.OperType.mintTC);\n        MintTCParams memory params = MintTCParams({\n            qTC: qTC_,\n            qACmax: qACmax,\n            sender: msg.sender,\n            recipient: recipient_,\n            vendor: vendor_\n        });\n        operId = MocQueue(mocQueue).queueMintTC(params);\n        _lockACInPending(qACmax);\n    }\n\n    /**\n     * @notice caller sends Collateral Token and recipient receives Collateral Asset\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not\n     * @param qTC_ amount of Collateral Token to redeem\n     * @param qACmin_ minimum amount of Collateral Asset that `recipient_` expects to receive\n     * @param recipient_ address who receives the Collateral Asset\n     * @param vendor_ address who receives a markup\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function _redeemTCtoViaVendor(\n        uint256 qTC_,\n        uint256 qACmin_,\n        address recipient_,\n        address vendor_\n    ) internal notLiquidated notPaused checkRecipient(msg.sender, recipient_) returns (uint256 operId) {\n        _transferExecFee(msg.value, MocQueueExecFees.OperType.redeemTC);\n        RedeemTCParams memory params = RedeemTCParams({\n            qTC: qTC_,\n            qACmin: qACmin_,\n            sender: msg.sender,\n            recipient: recipient_,\n            vendor: vendor_\n        });\n        operId = MocQueue(mocQueue).queueRedeemTC(params);\n        _lockTCInPending(qTC_);\n    }\n\n    /**\n     * @notice caller sends Collateral Asset and recipient receives Pegged Token\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not\n     *   Requires prior sender approval of Collateral Asset to this contract\n     * @param tp_ Pegged Token address to mint\n     * @param qTP_ amount of Pegged Token to mint\n     * @param qACmax_ maximum amount of Collateral Asset that can be spent\n     * @param recipient_ address who receives the Pegged Token\n     * @param vendor_ address who receives a markup\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function _mintTPtoViaVendor(\n        address tp_,\n        uint256 qTP_,\n        uint256 qACmax_,\n        address recipient_,\n        address vendor_\n    ) internal notLiquidated notPaused checkRecipient(msg.sender, recipient_) returns (uint256 operId) {\n        uint256 qACmax = _transferExecFee(qACmax_, MocQueueExecFees.OperType.mintTP);\n        MintTPParams memory params = MintTPParams({\n            tp: tp_,\n            qTP: qTP_,\n            qACmax: qACmax,\n            sender: msg.sender,\n            recipient: recipient_,\n            vendor: vendor_\n        });\n        operId = MocQueue(mocQueue).queueMintTP(params);\n        _lockACInPending(qACmax);\n    }\n\n    /**\n     * @notice caller sends Pegged Token and recipient receives Collateral Asset\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not\n     * @param tp_ Pegged Token address to redeem\n     * @param qTP_ amount of Pegged Token to redeem\n     * @param qACmin_ minimum amount of Collateral Asset that `recipient_` expects to receive\n     * @param recipient_ address who receives the Collateral Asset\n     * @param vendor_ address who receives a markup\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function _redeemTPtoViaVendor(\n        address tp_,\n        uint256 qTP_,\n        uint256 qACmin_,\n        address recipient_,\n        address vendor_\n    ) internal notLiquidated notPaused checkRecipient(msg.sender, recipient_) returns (uint256 operId) {\n        _transferExecFee(msg.value, MocQueueExecFees.OperType.redeemTP);\n        RedeemTPParams memory params = RedeemTPParams({\n            tp: tp_,\n            qTP: qTP_,\n            qACmin: qACmin_,\n            sender: msg.sender,\n            recipient: recipient_,\n            vendor: vendor_\n        });\n        operId = MocQueue(mocQueue).queueRedeemTP(params);\n        _lockTPInPending(IERC20Upgradeable(tp_), qTP_);\n    }\n\n    /**\n     * @notice caller sends Collateral Asset and recipient receives Collateral Token and Pegged Token\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not\n     *  Requires prior sender approval of Collateral Asset to this contract\n     *  This operation is done without checking coverage\n     *  Collateral Token and Pegged Token are minted in equivalent proportions so that its price\n     *  and global coverage are not modified.\n     *  Reverts if qAC sent are insufficient.\n     * @param tp_ Pegged Token address\n     * @param qTP_ amount of Pegged Token to mint\n     * @param qACmax_ maximum amount of Collateral Asset that can be spent\n     * @param recipient_ address who receives the Collateral Token and Pegged Token\n     * @param vendor_ address who receives a markup\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function _mintTCandTPtoViaVendor(\n        address tp_,\n        uint256 qTP_,\n        uint256 qACmax_,\n        address recipient_,\n        address vendor_\n    ) internal notLiquidated notPaused checkRecipient(msg.sender, recipient_) returns (uint256 operId) {\n        uint256 qACmax = _transferExecFee(qACmax_, MocQueueExecFees.OperType.mintTCandTP);\n        MintTCandTPParams memory params = MintTCandTPParams({\n            tp: tp_,\n            qTP: qTP_,\n            qACmax: qACmax,\n            sender: msg.sender,\n            recipient: recipient_,\n            vendor: vendor_\n        });\n        operId = MocQueue(mocQueue).queueMintTCandTP(params);\n        _lockACInPending(qACmax);\n    }\n\n    /**\n     * @notice Caller sends Collateral Token and Pegged Token and recipient receives Collateral Asset.\n     *  `vendor_` receives a markup in Fee Token if possible or in Collateral Asset if not\n     *  This operation is done without checking coverage\n     *  Collateral Token and Pegged Token are redeemed in equivalent proportions so that their price\n     *  and global coverage are not modified.\n     *  Reverts if qTC sent are insufficient.\n     * @param tp_ Pegged Token address\n     * @param qTC_ Maximum amount of Collateral Token to redeem\n     * @param qTP_ Amount of Pegged Token to redeem\n     * @param qACmin_ Minimum amount of Collateral Asset that `recipient_` expects to receive\n     * @param recipient_ Address who receives the Collateral Asset\n     * @param vendor_ Address who receives a markup\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function _redeemTCandTPtoViaVendor(\n        address tp_,\n        uint256 qTC_,\n        uint256 qTP_,\n        uint256 qACmin_,\n        address recipient_,\n        address vendor_\n    ) internal notLiquidated notPaused checkRecipient(msg.sender, recipient_) returns (uint256 operId) {\n        _transferExecFee(msg.value, MocQueueExecFees.OperType.redeemTCandTP);\n        RedeemTCandTPParams memory params = RedeemTCandTPParams({\n            tp: tp_,\n            qTC: qTC_,\n            qTP: qTP_,\n            qACmin: qACmin_,\n            sender: msg.sender,\n            recipient: recipient_,\n            vendor: vendor_\n        });\n        operId = MocQueue(mocQueue).queueRedeemTCandTP(params);\n        _lockTCInPending(qTC_);\n        _lockTPInPending(IERC20Upgradeable(tp_), qTP_);\n    }\n\n    /**\n     * @notice caller sends a Pegged Token and recipient receives another one\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not\n     * @param tpFrom_ owned Pegged Token address\n     * @param tpTo_ target Pegged Token address\n     * @param qTP_ amount of owned Pegged Token to swap\n     * @param qTPmin_ minimum amount of target Pegged Token that `recipient_` expects to receive\n     * @param qACmax_ maximum amount of Collateral Asset that can be spent in fees\n     * @param recipient_ address who receives the target Pegged Token\n     * @param vendor_ address who receives a markup\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function _swapTPforTPtoViaVendor(\n        address tpFrom_,\n        address tpTo_,\n        uint256 qTP_,\n        uint256 qTPmin_,\n        uint256 qACmax_,\n        address recipient_,\n        address vendor_\n    ) internal notLiquidated notPaused checkRecipient(msg.sender, recipient_) returns (uint256 operId) {\n        uint256 qACmax = _transferExecFee(qACmax_, MocQueueExecFees.OperType.swapTPforTP);\n        SwapTPforTPParams memory params = SwapTPforTPParams({\n            tpFrom: tpFrom_,\n            tpTo: tpTo_,\n            qTP: qTP_,\n            qTPmin: qTPmin_,\n            qACmax: qACmax,\n            sender: msg.sender,\n            recipient: recipient_,\n            vendor: vendor_\n        });\n        operId = MocQueue(mocQueue).queueSwapTPforTP(params);\n        _lockTPInPending(IERC20Upgradeable(tpFrom_), qTP_);\n        _lockACInPending(qACmax);\n    }\n\n    /**\n     * @notice caller sends a Pegged Token and recipient receives Collateral Token\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not\n     * @param tp_ Pegged Token address\n     * @param qTP_ amount of owned Pegged Token to swap\n     * @param qTCmin_ minimum amount of Collateral Token that `recipient_` expects to receive\n     * @param qACmax_ maximum amount of Collateral Asset that can be spent in fees\n     * @param recipient_ address who receives the Collateral Token\n     * @param vendor_ address who receives a markup\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function _swapTPforTCtoViaVendor(\n        address tp_,\n        uint256 qTP_,\n        uint256 qTCmin_,\n        uint256 qACmax_,\n        address recipient_,\n        address vendor_\n    ) internal notLiquidated notPaused checkRecipient(msg.sender, recipient_) returns (uint256 operId) {\n        uint256 qACmax = _transferExecFee(qACmax_, MocQueueExecFees.OperType.swapTPforTC);\n        SwapTPforTCParams memory params = SwapTPforTCParams({\n            tp: tp_,\n            qTP: qTP_,\n            qTCmin: qTCmin_,\n            qACmax: qACmax,\n            sender: msg.sender,\n            recipient: recipient_,\n            vendor: vendor_\n        });\n        operId = MocQueue(mocQueue).queueSwapTPforTC(params);\n        _lockTPInPending(IERC20Upgradeable(tp_), qTP_);\n        _lockACInPending(qACmax);\n    }\n\n    /**\n     * @notice Caller sends a Collateral Token and recipient receives Pegged Token.\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not.\n     * @param tp_ Pegged Token address\n     * @param qTC_ Amount of owned Collateral Token to swap\n     * @param qTPmin_ Minimum amount of Pegged Token that `recipient_` expects to receive\n     * @param qACmax_ Maximum amount of Collateral Asset that can be spent in fees\n     * @param recipient_ Address who receives the Pegged Token\n     * @param vendor_ Address who receives a markup\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function _swapTCforTPtoViaVendor(\n        address tp_,\n        uint256 qTC_,\n        uint256 qTPmin_,\n        uint256 qACmax_,\n        address recipient_,\n        address vendor_\n    ) internal notLiquidated notPaused checkRecipient(msg.sender, recipient_) returns (uint256 operId) {\n        uint256 qACmax = _transferExecFee(qACmax_, MocQueueExecFees.OperType.swapTCforTP);\n        SwapTCforTPParams memory params = SwapTCforTPParams({\n            tp: tp_,\n            qTC: qTC_,\n            qTPmin: qTPmin_,\n            qACmax: qACmax,\n            sender: msg.sender,\n            recipient: recipient_,\n            vendor: vendor_\n        });\n        operId = MocQueue(mocQueue).queueSwapTCforTP(params);\n        _lockTCInPending(qTC_);\n        _lockACInPending(qACmax);\n    }\n\n    // ------- External functions -------\n\n    /**\n     * @notice caller sends Collateral Token and recipient receives Collateral Asset\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not\n     * @param qTC_ amount of Collateral Token to redeem\n     * @param qACmin_ minimum amount of Collateral Asset that `recipient_` expects to receive\n     * @param recipient_ address who receives the Collateral Asset\n     * @param vendor_ address who receives a markup, `0x0` if not using a vendor\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function redeemTC(\n        uint256 qTC_,\n        uint256 qACmin_,\n        address recipient_,\n        address vendor_\n    ) external payable returns (uint256 operId) {\n        return _redeemTCtoViaVendor(qTC_, qACmin_, recipient_, vendor_);\n    }\n\n    /**\n     * @notice caller sends Pegged Token and recipient receives Collateral Asset\n     *  `vendor_` receives a markup in Fee Token if possible or in qAC if not\n     * @param tp_ Pegged Token address to redeem\n     * @param qTP_ amount of Pegged Token to redeem\n     * @param qACmin_ minimum amount of Collateral Asset that `recipient_` expects to receive\n     * @param recipient_ address who receives the Collateral Asset\n     * @param vendor_ address who receives a markup, `0x0` if not using a vendor\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function redeemTP(\n        address tp_,\n        uint256 qTP_,\n        uint256 qACmin_,\n        address recipient_,\n        address vendor_\n    ) external payable returns (uint256 operId) {\n        return _redeemTPtoViaVendor(tp_, qTP_, qACmin_, recipient_, vendor_);\n    }\n\n    /**\n     * @notice Caller sends Collateral Token and Pegged Token and recipient receives Collateral Asset.\n     *  `vendor_` receives a markup in Fee Token if possible or in Collateral Asset if not\n     *  This operation is done without checking coverage\n     *  Collateral Token and Pegged Token are redeemed in equivalent proportions so that their price\n     *  and global coverage are not modified.\n     *  Reverts if qTC sent are insufficient.\n     * @param tp_ Pegged Token address\n     * @param qTC_ Maximum amount of Collateral Token to redeem\n     * @param qTP_ Amount of Pegged Token to redeem\n     * @param qACmin_ Minimum amount of Collateral Asset that `recipient_` expects to receive\n     * @param recipient_ Address who receives the Collateral Asset\n     * @param vendor_ address who receives a markup, `0x0` if not using a vendor\n     * @return operId Identifier to track the Operation lifecycle\n     */\n    function redeemTCandTP(\n        address tp_,\n        uint256 qTC_,\n        uint256 qTP_,\n        uint256 qACmin_,\n        address recipient_,\n        address vendor_\n    ) external payable returns (uint256 operId) {\n        return _redeemTCandTPtoViaVendor(tp_, qTC_, qTP_, qACmin_, recipient_, vendor_);\n    }\n\n    // ------- External Only Queue Functions -------\n\n    /**\n     * @notice executes Operation based on params, only mocQueue allowed\n     * see MocCore _mintTCto for details\n     */\n    function execMintTC(\n        MintTCParams calldata params_\n    ) external onlyMocQueue returns (uint256 qACtotalNeeded, FeeCalcs memory feeCalcs) {\n        return _mintTCto(params_);\n    }\n\n    /**\n     * @notice executes Operation based on params, only mocQueue allowed\n     * see MocCore _redeemTCto for details\n     */\n    function execRedeemTC(\n        RedeemTCParams calldata params_\n    ) external onlyMocQueue returns (uint256 qACtoRedeem, FeeCalcs memory feeCalcs) {\n        return _redeemTCto(params_);\n    }\n\n    /**\n     * @notice executes Operation based on params, only mocQueue allowed\n     * see MocCore _mintTPto for details\n     */\n    function execMintTP(\n        MintTPParams calldata params_\n    ) external onlyMocQueue returns (uint256 qACtotalNeeded, FeeCalcs memory feeCalcs) {\n        return _mintTPto(params_);\n    }\n\n    /**\n     * @notice executes Operation based on params, only mocQueue allowed\n     * see MocCore _redeemTPto for details\n     */\n    function execRedeemTP(\n        RedeemTPParams calldata params_\n    ) external onlyMocQueue returns (uint256 qACtoRedeem, FeeCalcs memory feeCalcs) {\n        return _redeemTPto(params_);\n    }\n\n    /**\n     * @notice executes Operation based on params, only mocQueue allowed\n     * see MocCore _mintTCandTPto for details\n     */\n    function execMintTCandTP(\n        MintTCandTPParams calldata params_\n    )\n        external\n        onlyMocQueue\n        returns (\n            uint256 qACtoMintTC,\n            uint256 qACtoMintTP,\n            uint256 qACtoSpent,\n            uint256 qTCMinted,\n            FeeCalcs memory feeCalcs\n        )\n    {\n        return _mintTCandTPto(params_);\n    }\n\n    /**\n     * @notice executes Operation based on params, only mocQueue allowed\n     * see MocCore _redeemTCandTPto for details\n     */\n    function execRedeemTCandTP(\n        RedeemTCandTPParams calldata params_\n    )\n        external\n        onlyMocQueue\n        returns (\n            uint256 qACtoRedeemTC,\n            uint256 qACtoRedeemTP,\n            uint256 qACtoReceive,\n            uint256 qTCRedeemed,\n            FeeCalcs memory feeCalcs\n        )\n    {\n        (qACtoRedeemTC, qACtoRedeemTP, qACtoReceive, qTCRedeemed, feeCalcs) = _redeemTCandTPto(params_);\n        // return the unused locked TCs\n        unchecked {\n            uint256 qTCDif = params_.qTC - qTCRedeemed;\n            SafeERC20Upgradeable.safeTransfer(tcToken, params_.sender, qTCDif);\n        }\n    }\n\n    /**\n     * @notice executes Operation based on params, only mocQueue allowed\n     * see MocCore _swapTCforTPto for details\n     */\n    function execSwapTCforTP(\n        SwapTCforTPParams calldata params_\n    ) external onlyMocQueue returns (uint256 qTPMinted, FeeCalcs memory feeCalcs) {\n        return _swapTCforTPto(params_);\n    }\n\n    /**\n     * @notice executes Operation based on params, only mocQueue allowed\n     * see MocCore _swapTPforTCto for details\n     */\n    function execSwapTPforTC(\n        SwapTPforTCParams calldata params_\n    ) external onlyMocQueue returns (uint256 qTCMinted, FeeCalcs memory feeCalcs) {\n        return _swapTPforTCto(params_);\n    }\n\n    /**\n     * @notice executes Operation based on params, only mocQueue allowed\n     * see MocCore _swapTPforTPto for details\n     */\n    function execSwapTPforTP(\n        SwapTPforTPParams calldata params_\n    ) external onlyMocQueue returns (uint256 qTPMinted, FeeCalcs memory feeCalcs) {\n        return _swapTPforTPto(params_);\n    }\n\n    /**\n     * @notice while executing a pending Operation, if it fails we need to unlock user's tokens\n     * @param owner_ funds owner, address to be returned to\n     * @param qTCToUnlock_ TC amount to be unlocked\n     */\n    function unlockTCInPending(address owner_, uint256 qTCToUnlock_) external onlyMocQueue {\n        SafeERC20Upgradeable.safeTransfer(tcToken, owner_, qTCToUnlock_);\n    }\n\n    /**\n     * @notice while executing a pending Operation, if it fails we need to unlock user's tokens\n     * @param owner_ funds owner, address to be returned to\n     * @param tpToken_ TP to be unlocked\n     * @param qTPToUnlock_ TP amount to be unlocked\n     */\n    function unlockTPInPending(address owner_, IERC20Upgradeable tpToken_, uint256 qTPToUnlock_) external onlyMocQueue {\n        SafeERC20Upgradeable.safeTransfer(tpToken_, owner_, qTPToUnlock_);\n    }\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/Utils.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocOperations } from \"@moc/moc-main/contracts/core/MocOperations.sol\";\nimport { IPriceProvider } from \"@moc/moc-main/contracts/interfaces/IPriceProvider.sol\";\n\nlibrary Utils {\n    /**\n     * @notice Checks if the price is valid.\n     * @param priceProvider_ The price provider to check.\n     * @return valid True if the price is valid, false otherwise.\n     */\n    function _isValidPrice(address priceProvider_) internal view returns (bool) {\n        (, bool valid) = IPriceProvider(priceProvider_).peek();\n        return valid;\n    }\n\n    /**\n     * @notice Checks if the TP prices are valid.\n     * @param mocOperations_ The MocOperations contract to check.\n     * @return valid True if all prices are valid, false otherwise.\n     */\n    function _areValidPrices(address mocOperations_) internal view returns (bool) {\n        uint256 tpLength = MocOperations(mocOperations_).getTpAmount();\n        for (uint256 i = 0; i < tpLength; i++) {\n            (, IPriceProvider priceProvider) = MocOperations(mocOperations_).pegContainer(i);\n            if (!Utils._isValidPrice(address(priceProvider))) {\n                return false;\n            }\n        }\n        return true;\n    }\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/mocFlow/buffer/TaskLiquidate.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../../ITask.sol\";\n\ncontract TaskLiquidate is ITask {\n    IBuffer public immutable buffer;\n\n    /**\n     * @notice Constructor\n     * @param buffer_ The address of the buffer contract.\n     */\n    constructor(address buffer_) {\n        buffer = IBuffer(buffer_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() external view returns (bool) {\n        return buffer.isLiquidable();\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        buffer.liquidate();\n    }\n}\n\ninterface IBuffer {\n    function isLiquidable() external view returns (bool);\n    function liquidate() external;\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/mocFlow/commissionSplitter/TaskSplit.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../../ITask.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract TaskSplit is ITask {\n    address private constant COINBASE = address(0);\n\n    error TaskNotAvailable();\n\n    ICommissionSplitter public immutable commissionSplitter;\n    address token;\n    address feeToken;\n    uint256 public immutable tokenBalanceThreshold;\n    uint256 public immutable feeTokenBalanceThreshold;\n\n    /**\n     * @notice Constructor\n     * @param commissionSplitter_ The address of the commission splitter contract.\n     * @param token_ The address of the token to split. Use address(0) for coinbase.\n     * @param feeToken_ The address of the fee token to split, can be zero if not applicable.\n     * @param tokenBalanceThreshold_ The minimum balance of the token required to perform the split.\n     * @param feeTokenBalanceThreshold_ The minimum balance of the fee token required to perform the split.\n     */\n    constructor(\n        address commissionSplitter_,\n        address token_,\n        address feeToken_,\n        uint256 tokenBalanceThreshold_,\n        uint256 feeTokenBalanceThreshold_\n    ) {\n        commissionSplitter = ICommissionSplitter(commissionSplitter_);\n        token = token_;\n        feeToken = feeToken_;\n        tokenBalanceThreshold = tokenBalanceThreshold_;\n        feeTokenBalanceThreshold = feeTokenBalanceThreshold_;\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() external view returns (bool) {\n        return _splitAvailable(commissionSplitter);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        commissionSplitter.split();\n    }\n\n    /**\n     * @notice Check if the commission splitter has enough balance to split.\n     * @param commissionSplitter_ The commission splitter contract.\n     * @return bool True if the commission splitter can split, false otherwise.\n     */\n    function _splitAvailable(ICommissionSplitter commissionSplitter_) internal view returns (bool) {\n        uint256 tokenBalance = balanceOf(address(commissionSplitter_));\n        // CommissionSplitter may not have a feeToken, in that case we only check the token balance\n        uint256 feeTokenBalance = feeToken == address(0) ? 0 : IERC20(feeToken).balanceOf(address(commissionSplitter_));\n        return tokenBalance >= tokenBalanceThreshold || feeTokenBalance >= feeTokenBalanceThreshold;\n    }\n\n    /**\n     * @notice get the balance of the contract\n     * @param account_ address to check the balance\n     * @return balance of the contract\n     */\n    function balanceOf(address account_) internal view returns (uint256) {\n        if (token == COINBASE) {\n            return account_.balance;\n        } else {\n            return IERC20(token).balanceOf(account_);\n        }\n    }\n}\n\ninterface ICommissionSplitter {\n    function split() external;\n    function tokenGovern() external view returns (IERC20);\n}\n"},{"file_path":"project/contracts/changers/addTasksRunnerChanger/AddTasksRunnerChanger.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IChangeContract } from \"moc-main-latest/contracts/interfaces/IChangeContract.sol\";\nimport { MocMultiCollateralGuard, MocOperations } from \"moc-main-latest/contracts/multiCollateral/MocMultiCollateralGuard.sol\";\nimport { BucketParams } from \"moc-main-latest/contracts/multiCollateral/MocMultiCollateralBase.sol\";\nimport { PeggedTokenParams } from \"moc-main-latest/contracts/core/MocCommons.sol\";\nimport { IPriceProvider } from \"moc-main-latest/contracts/interfaces/IPriceProvider.sol\";\nimport { MocQueue } from \"moc-main-latest/contracts/queue/MocQueue.sol\";\nimport { MocQueueExecFees } from \"moc-main-latest/contracts/queue/MocQueueExecFees.sol\";\nimport { MocRC20 } from \"moc-main-latest/contracts/tokens/MocRC20.sol\";\nimport { CommissionSplitterBase } from \"moc-main-latest/contracts/auxiliary/CommissionSplitterBase.sol\";\nimport { MocRif } from \"../../MocRif.sol\";\n\ninterface ITasksRunner {\n    function addTask(address task) external;\n}\n\ninterface ICoinPairPriceGovernance {\n    function addPricePeekWhitelist(address _account) external;\n    function isPricePeekWhitelisted(address _account) external view returns (bool);\n}\n\ninterface IReverseAuction {\n    function setOutputAccount(address outputAccount_) external;\n    function setPriceProvider(address priceProvider_) external;\n}\n\ninterface IBufferLike {\n    function addOutput(address payable output, uint256 split, uint256 threshold) external;\n    function removeOutput(uint256 idx) external;\n    function getOutput(uint256 idx) external view returns (address, uint256, uint256, uint256);\n}\n\ninterface IGovernedRegistry {\n    function getAddress(bytes32 _key) external view returns (address);\n    function removeAddressArrayElement(bytes32 _key, address value) external;\n}\n\ninterface IMocMultiCollateralGuardPriceUpdates {\n    function setPriceUpdatesFeeRecipient(address priceUpdatesFeeRecipient_) external;\n}\n\n/**\n * @title AddTasksRunnerChanger\n * @notice This contract is a ChangeContract intended to be used with Moc Aeropulus\n * governance system.\n * @dev 1. Upgrade MocCore & MocQueue for RIF and DOC buckets\n *      2. Set new MocCoreExpansion for RIF and DOC buckets\n *      3. Upgrade MocMultiCollateralGuard\n *      4. Set coinbase execution fee recipient (RevAuction RBTCtoMOC -> TasksRunner)\n *      5. Set rebalance execution fee recipient for RIF and DOC buckets\n *         (RevAuction RIFtoMOC and DOCtoMOC -> TasksRunner)\n *      6. Set price updates fee recipient (RevAuction RBTCtoMOC -> SplitPriceUpdateFeesToBtcOracleAndRifOracle)\n *      7. Replace the RIF bucket direct price provider with the already-deployed RIF/USD CoinPair\n *      8. Whitelist consumers on the already-deployed RIF/USD CoinPair\n *      9. Add tasks to the already-deployed TasksRunner\n *      10. Set newly deployed reverse auctions output to TasksRunner\n *      11. Rewire commission splitters and buffers that fund Foundation / oracle infra\n *      12. Rewire legacy RIF-based reverse auctions to the replacement providers\n *      13. Remove old reverse auctions and buffers from governed registry\n *.     14. Reset useMaxLastPublication block because DOC bucket always has a valid price(it does not use conditional price)\n */\ncontract AddTasksRunnerChanger is IChangeContract {\n    bytes32 private constant MOC_FLOW_BUFFERS = 0x4cb845794d5472a713e41e8e4ddc566dab8d695f1dc6c8edd43dad9d55112a22;\n    bytes32 private constant MOC_FLOW_REVERSE_AUCTIONS =\n        0x0428ec087e0cce276a71d1caf1afe4da32a2d48b3ebe579040612b5bd262ff73;\n    bytes32 private constant INFO_ADDR = 0xda9f12e01fc92de345bb741448d36ecb967052dd7aa1670439af833c9a3d78f1;\n\n    MocMultiCollateralGuard public immutable mocMultiCollateralGuard;\n    address public immutable mocMultiCollateralGuardImplementation;\n    address public immutable mocCoreRifBucketImplementation;\n    address public immutable mocCoreDocBucketImplementation;\n    address public immutable mocQueueRifBucketImplementation;\n    address public immutable mocQueueDocBucketImplementation;\n    address public immutable mocCoreExpansionRifBucket;\n    address public immutable mocCoreExpansionDocBucket;\n    address payable public immutable revAuctionRBTCtoMOC_tasksRunner;\n    address public immutable revAuctionRIFtoMOC_tasksRunner;\n    address public immutable revAuctionDOCtoMOC_tasksRunner;\n    address public immutable revAuctionRBTCtoMOC_rocNodes;\n    address public immutable revAuctionRIFtoMOC_rocRewardsBuffer;\n    address public immutable revAuctionMOCtoRIF_rifBucket;\n    address public immutable revAuctionDOCtoMOC_rocRewardsBuffer;\n    address public immutable revAuctionMOCtoDOC_docBucket;\n    address public immutable revAuctionRBTCtoMOC_mocRewardsBuffer;\n    address public immutable revAuctionMOCtoRBTC_mocV1;\n    address public immutable rifProRewardsBuffer_rocRewardsBuffer;\n    address public immutable rocrRewardsBuffer;\n    address public immutable bitProRewardsBuffer;\n    address public immutable bproRewardsBuffer;\n    address public immutable mocRewardsBuffer;\n    IGovernedRegistry public immutable governedRegistry;\n    address public immutable tasksRunner;\n    address public immutable taskExecuteQueueV3;\n    address public immutable taskUpdateEmaV3RifBucket;\n    MocRif public immutable rifBucket;\n    address public immutable rifOracleCoinPair;\n    address public immutable rifToRbtcPriceProvider;\n    address public immutable rifToMocPriceProvider;\n    address public immutable mocToRifPriceProvider;\n    CommissionSplitterBase public immutable rifCommissionSplitterV2;\n    CommissionSplitterBase public immutable rifCommissionSplitterV3;\n    CommissionSplitterBase public immutable docCommissionSplitterV2;\n    address public immutable splitRifFeesToFoundationAndRifOracle;\n    address public immutable splitDocFeesToFoundationAndRifOracle;\n    address public immutable splitMocFeesToFoundationAndRifOracle;\n    address public immutable splitMocRewardsToBtcOracleAndTasksRunner;\n    address public immutable splitPriceUpdateFeesToBtcOracleAndRifOracle;\n    address public immutable btcUsdCoinPair;\n    uint256 public immutable mocRewardsBufferBtcUsdOutputIndex;\n    uint256 public immutable rifBucketUsdrifTargetEma;\n    uint256[] private rifBucketExecutionCosts;\n    uint256[] private docBucketExecutionCosts;\n    address[] private tasks;\n\n    /**\n    @notice Constructor\n    @param mocMultiCollateralGuard_ Address of the proxy mocMultiCollateralGuard\n    @param mocMultiCollateralGuardImplementation_ New implementation for MocMultiCollateralGuard proxy\n    @param mocCoreRifBucketImplementation_ New implementation for RIF bucket MocCore proxy\n    @param mocCoreDocBucketImplementation_ New implementation for DOC bucket MocCore proxy\n    @param mocQueueRifBucketImplementation_ New implementation for RIF bucket MocQueue proxy\n    @param mocQueueDocBucketImplementation_ New implementation for DOC bucket MocQueue proxy\n    @param mocCoreExpansionRifBucket_ New MocCoreExpansion for RIF bucket\n    @param mocCoreExpansionDocBucket_ New MocCoreExpansion for DOC bucket\n    @param revAuctionRBTCtoMOC_tasksRunner_ Address for coinbase execution fee recipient (TasksRunner)\n    @param revAuctionRIFtoMOC_tasksRunner_ Address for RIF bucket rebalance execution fee recipient (TasksRunner)\n    @param revAuctionDOCtoMOC_tasksRunner_ Address for DOC bucket rebalance execution fee recipient (TasksRunner)\n    @param revAuctionRBTCtoMOC_rocNodes_ Address for price updates fee recipient (SplitPriceUpdateFeesToBtcOracleAndRifOracle)\n    @param revAuctionRIFtoMOC_rocRewardsBuffer_ Address for RevAuction RIFtoMOC output recipient\n    @param revAuctionMOCtoRIF_rifBucket_ Address of current RevAuction MOCtoRIF (registered in flow reverse auctions)\n    @param revAuctionDOCtoMOC_rocRewardsBuffer_ Address for RevAuction DOCtoMOC output recipient\n    @param revAuctionMOCtoDOC_docBucket_ Address of current RevAuction MOCtoDOC (registered in flow reverse auctions)\n    @param revAuctionRBTCtoMOC_mocRewardsBuffer_ Address of current RevAuction RBTCtoMOC for MocRewardsBuffer\n    @param revAuctionMOCtoRBTC_mocV1_ Address of current RevAuction MOCtoRBTC for mocV1\n    @param rifProRewardsBuffer_rocRewardsBuffer_ Address for RifProRewardsBuffer output recipient\n    @param rocrRewardsBuffer_ Address of RocrRewardsBuffer (registered in flow buffers)\n    @param bitProRewardsBuffer_ Address of BitProRewardsBuffer (registered in flow buffers)\n    @param bproRewardsBuffer_ Address of BproRewardsBuffer (registered in flow buffers)\n    @param mocRewardsBuffer_ Address of MocRewardsBuffer (registered in flow buffers)\n    @param governedRegistry_ Governed registry where old flow addresses are removed\n    @param tasksRunner_ Already-deployed TasksRunner contract to add tasks to\n    @param tasks_ List of task addresses to add to the already-deployed TasksRunner\n    @param taskExecuteQueueV3_ Deployed task that checks bucket prices before queue execution\n    @param taskUpdateEmaV3RifBucket_ Deployed RIF-bucket EMA task that checks direct TP prices\n    @param rifBucket_ RIF bucket whose direct price provider is set to the already-deployed RIF/USD CoinPair\n    @param rifOracleCoinPair_ Already-deployed direct RIF/USD CoinPair contract\n    @param rifToRbtcPriceProvider_ Replacement RIF/BTC provider using the new direct RIF/USD CoinPair\n    @param rifToMocPriceProvider_ Replacement RIF/MOC provider using the new direct RIF/USD CoinPair\n    @param mocToRifPriceProvider_ Replacement MOC/RIF provider using the new direct RIF/USD CoinPair\n    @param rifCommissionSplitterV2_ Live RIF commission splitter V2 whose Foundation branches are rewired in-place\n    @param rifCommissionSplitterV3_ Live RIF commission splitter V3 whose Foundation branches are rewired in-place\n    @param docCommissionSplitterV2_ Live DOC commission splitter V2 whose Foundation branches are rewired in-place\n    @param splitRifFeesToFoundationAndRifOracle_ New RIF fee-routing buffer splitting 70% to Foundation and 30% to the new RIF/USD oracle\n    @param splitDocFeesToFoundationAndRifOracle_ New DOC fee-routing buffer splitting 70% to Foundation and 30% to the new RIF/USD oracle\n    @param splitMocFeesToFoundationAndRifOracle_ New MOC fee-routing buffer splitting 70% to Foundation and 30% to the new RIF/USD oracle\n    @param splitMocRewardsToBtcOracleAndTasksRunner_ New child buffer splitting the BTC/USD oracle branch 90/10 between BTC/USD and TasksRunner\n    @param splitPriceUpdateFeesToBtcOracleAndRifOracle_ New MOC buffer splitting queue price-update fees 50/50 between BTC/USD and RIF/USD\n    @param btcUsdCoinPair_ Existing BTC/USD CoinPair currently used by the mocRewardsBuffer top-level oracle branch\n    @param mocRewardsBufferBtcUsdOutputIndex_ Static output index of the BTC/USD branch on mocRewardsBuffer\n    @param rifBucketExecutionCosts_ Updated queue execution-cost payload for the RIF bucket queue, including priceUpdatesCost\n    @param docBucketExecutionCosts_ Updated queue execution-cost payload for the DOC bucket queue, including priceUpdatesCost\n    @param rifBucketUsdrifTargetEma_ New target coverage EMA ratio (tpCtarg) to set on the usdRIF pegged token in the RIF bucket\n  */\n    constructor(\n        MocMultiCollateralGuard mocMultiCollateralGuard_,\n        address mocMultiCollateralGuardImplementation_,\n        address mocCoreRifBucketImplementation_,\n        address mocCoreDocBucketImplementation_,\n        address mocQueueRifBucketImplementation_,\n        address mocQueueDocBucketImplementation_,\n        address mocCoreExpansionRifBucket_,\n        address mocCoreExpansionDocBucket_,\n        address payable revAuctionRBTCtoMOC_tasksRunner_,\n        address revAuctionRIFtoMOC_tasksRunner_,\n        address revAuctionDOCtoMOC_tasksRunner_,\n        address revAuctionRBTCtoMOC_rocNodes_,\n        address revAuctionRIFtoMOC_rocRewardsBuffer_,\n        address revAuctionMOCtoRIF_rifBucket_,\n        address revAuctionDOCtoMOC_rocRewardsBuffer_,\n        address revAuctionMOCtoDOC_docBucket_,\n        address revAuctionRBTCtoMOC_mocRewardsBuffer_,\n        address revAuctionMOCtoRBTC_mocV1_,\n        address rifProRewardsBuffer_rocRewardsBuffer_,\n        address rocrRewardsBuffer_,\n        address bitProRewardsBuffer_,\n        address bproRewardsBuffer_,\n        address mocRewardsBuffer_,\n        IGovernedRegistry governedRegistry_,\n        address tasksRunner_,\n        address[] memory tasks_,\n        address taskExecuteQueueV3_,\n        address taskUpdateEmaV3RifBucket_,\n        MocRif rifBucket_,\n        address rifOracleCoinPair_,\n        address rifToRbtcPriceProvider_,\n        address rifToMocPriceProvider_,\n        address mocToRifPriceProvider_,\n        CommissionSplitterBase rifCommissionSplitterV2_,\n        CommissionSplitterBase rifCommissionSplitterV3_,\n        CommissionSplitterBase docCommissionSplitterV2_,\n        address splitRifFeesToFoundationAndRifOracle_,\n        address splitDocFeesToFoundationAndRifOracle_,\n        address splitMocFeesToFoundationAndRifOracle_,\n        address splitMocRewardsToBtcOracleAndTasksRunner_,\n        address splitPriceUpdateFeesToBtcOracleAndRifOracle_,\n        address btcUsdCoinPair_,\n        uint256 mocRewardsBufferBtcUsdOutputIndex_,\n        uint256[] memory rifBucketExecutionCosts_,\n        uint256[] memory docBucketExecutionCosts_,\n        uint256 rifBucketUsdrifTargetEma_\n    ) {\n        mocMultiCollateralGuard = mocMultiCollateralGuard_;\n        mocMultiCollateralGuardImplementation = mocMultiCollateralGuardImplementation_;\n        mocCoreRifBucketImplementation = mocCoreRifBucketImplementation_;\n        mocCoreDocBucketImplementation = mocCoreDocBucketImplementation_;\n        mocQueueRifBucketImplementation = mocQueueRifBucketImplementation_;\n        mocQueueDocBucketImplementation = mocQueueDocBucketImplementation_;\n        mocCoreExpansionRifBucket = mocCoreExpansionRifBucket_;\n        mocCoreExpansionDocBucket = mocCoreExpansionDocBucket_;\n        revAuctionRBTCtoMOC_tasksRunner = revAuctionRBTCtoMOC_tasksRunner_;\n        revAuctionRIFtoMOC_tasksRunner = revAuctionRIFtoMOC_tasksRunner_;\n        revAuctionDOCtoMOC_tasksRunner = revAuctionDOCtoMOC_tasksRunner_;\n        revAuctionRBTCtoMOC_rocNodes = revAuctionRBTCtoMOC_rocNodes_;\n        revAuctionRIFtoMOC_rocRewardsBuffer = revAuctionRIFtoMOC_rocRewardsBuffer_;\n        revAuctionMOCtoRIF_rifBucket = revAuctionMOCtoRIF_rifBucket_;\n        revAuctionDOCtoMOC_rocRewardsBuffer = revAuctionDOCtoMOC_rocRewardsBuffer_;\n        revAuctionMOCtoDOC_docBucket = revAuctionMOCtoDOC_docBucket_;\n        revAuctionRBTCtoMOC_mocRewardsBuffer = revAuctionRBTCtoMOC_mocRewardsBuffer_;\n        revAuctionMOCtoRBTC_mocV1 = revAuctionMOCtoRBTC_mocV1_;\n        rifProRewardsBuffer_rocRewardsBuffer = rifProRewardsBuffer_rocRewardsBuffer_;\n        rocrRewardsBuffer = rocrRewardsBuffer_;\n        bitProRewardsBuffer = bitProRewardsBuffer_;\n        bproRewardsBuffer = bproRewardsBuffer_;\n        mocRewardsBuffer = mocRewardsBuffer_;\n        governedRegistry = governedRegistry_;\n        tasksRunner = tasksRunner_;\n        tasks = tasks_;\n        taskExecuteQueueV3 = taskExecuteQueueV3_;\n        taskUpdateEmaV3RifBucket = taskUpdateEmaV3RifBucket_;\n        rifBucket = rifBucket_;\n        rifOracleCoinPair = rifOracleCoinPair_;\n        rifToRbtcPriceProvider = rifToRbtcPriceProvider_;\n        rifToMocPriceProvider = rifToMocPriceProvider_;\n        mocToRifPriceProvider = mocToRifPriceProvider_;\n        rifCommissionSplitterV2 = rifCommissionSplitterV2_;\n        rifCommissionSplitterV3 = rifCommissionSplitterV3_;\n        docCommissionSplitterV2 = docCommissionSplitterV2_;\n        splitRifFeesToFoundationAndRifOracle = splitRifFeesToFoundationAndRifOracle_;\n        splitDocFeesToFoundationAndRifOracle = splitDocFeesToFoundationAndRifOracle_;\n        splitMocFeesToFoundationAndRifOracle = splitMocFeesToFoundationAndRifOracle_;\n        splitMocRewardsToBtcOracleAndTasksRunner = splitMocRewardsToBtcOracleAndTasksRunner_;\n        splitPriceUpdateFeesToBtcOracleAndRifOracle = splitPriceUpdateFeesToBtcOracleAndRifOracle_;\n        btcUsdCoinPair = btcUsdCoinPair_;\n        mocRewardsBufferBtcUsdOutputIndex = mocRewardsBufferBtcUsdOutputIndex_;\n        rifBucketExecutionCosts = rifBucketExecutionCosts_;\n        docBucketExecutionCosts = docBucketExecutionCosts_;\n        rifBucketUsdrifTargetEma = rifBucketUsdrifTargetEma_;\n    }\n\n    /**\n    @notice Execute the changes.\n    @dev Should be called by the governor, but this contract does not check that explicitly\n    because it is not its responsibility in the current architecture.\n   */\n    function execute() external {\n        MocOperations rifBucketOps = mocMultiCollateralGuard.buckets(0);\n        MocOperations docBucketOps = mocMultiCollateralGuard.buckets(1);\n        MocQueue rifQueue = MocQueue(rifBucketOps.mocQueue());\n        MocQueue docQueue = MocQueue(docBucketOps.mocQueue());\n\n        // 1) Upgrade buckets and queues\n        rifBucketOps.upgradeTo(mocCoreRifBucketImplementation);\n        docBucketOps.upgradeTo(mocCoreDocBucketImplementation);\n\n        rifQueue.upgradeTo(mocQueueRifBucketImplementation);\n        docQueue.upgradeTo(mocQueueDocBucketImplementation);\n\n        // 2) Update queue execution costs, adding the shared price-updates fee\n        _updateQueueExecutionCosts(rifQueue, rifBucketExecutionCosts);\n        _updateQueueExecutionCosts(docQueue, docBucketExecutionCosts);\n\n        // 3) Set MocCoreExpansion on buckets\n        rifBucketOps.setMocCoreExpansion(mocCoreExpansionRifBucket);\n        docBucketOps.setMocCoreExpansion(mocCoreExpansionDocBucket);\n\n        // 4) Upgrade MocMultiCollateralGuard\n        mocMultiCollateralGuard.upgradeTo(mocMultiCollateralGuardImplementation);\n\n        // 5) Set coinbase execution fee recipient\n        mocMultiCollateralGuard.setCoinbaseExecFeeRecipient(revAuctionRBTCtoMOC_tasksRunner);\n\n        // 6) Set rebalance execution fee recipients for RIF and DOC buckets\n        //    and wire the replacement RIF/BTC provider in the RIF bucket guard params\n        mocMultiCollateralGuard.editBucket(\n            rifBucketOps,\n            _buildBucketParams(rifBucketOps, revAuctionRIFtoMOC_tasksRunner, IPriceProvider(rifToRbtcPriceProvider))\n        );\n        mocMultiCollateralGuard.editBucket(\n            docBucketOps,\n            _buildBucketParams(\n                docBucketOps,\n                revAuctionDOCtoMOC_tasksRunner,\n                mocMultiCollateralGuard.acCoinbasePriceProvider(docBucketOps)\n            )\n        );\n\n        // 7) Set price updates fee recipient\n        IMocMultiCollateralGuardPriceUpdates(address(mocMultiCollateralGuard)).setPriceUpdatesFeeRecipient(\n            revAuctionRBTCtoMOC_rocNodes\n        );\n\n        // 8) Set the RIF bucket direct price provider to the already-deployed RIF/USD CoinPair\n        //    and whitelist its consumers\n        _ensureRifOracleWhitelist(rifOracleCoinPair);\n        _editRifBucketPriceProvider(rifOracleCoinPair);\n\n        // 9) Add tasks to the already-deployed TasksRunner\n        _addTasksToTasksRunner();\n\n        // 10) Set newly deployed reverse auctions output to TasksRunner\n        IReverseAuction(revAuctionRBTCtoMOC_tasksRunner).setOutputAccount(tasksRunner);\n        IReverseAuction(revAuctionRIFtoMOC_tasksRunner).setOutputAccount(tasksRunner);\n        IReverseAuction(revAuctionDOCtoMOC_tasksRunner).setOutputAccount(tasksRunner);\n\n        // 11) Rewire commission splitters and buffers that fund Foundation / oracle infra\n        _rewireOracleFundingFlows();\n\n        // 12) Rewire legacy RIF-based reverse auctions to the replacement providers\n        IReverseAuction(revAuctionRIFtoMOC_rocRewardsBuffer).setPriceProvider(rifToMocPriceProvider);\n        IReverseAuction(revAuctionMOCtoRIF_rifBucket).setPriceProvider(mocToRifPriceProvider);\n\n        // 13) Remove reverse auctions and buffers from governed registry\n        governedRegistry.removeAddressArrayElement(MOC_FLOW_REVERSE_AUCTIONS, revAuctionRIFtoMOC_rocRewardsBuffer);\n        governedRegistry.removeAddressArrayElement(MOC_FLOW_BUFFERS, rifProRewardsBuffer_rocRewardsBuffer);\n        governedRegistry.removeAddressArrayElement(MOC_FLOW_REVERSE_AUCTIONS, revAuctionMOCtoRIF_rifBucket);\n        governedRegistry.removeAddressArrayElement(MOC_FLOW_REVERSE_AUCTIONS, revAuctionDOCtoMOC_rocRewardsBuffer);\n        governedRegistry.removeAddressArrayElement(MOC_FLOW_REVERSE_AUCTIONS, revAuctionMOCtoDOC_docBucket);\n        governedRegistry.removeAddressArrayElement(MOC_FLOW_REVERSE_AUCTIONS, revAuctionRBTCtoMOC_mocRewardsBuffer);\n        governedRegistry.removeAddressArrayElement(MOC_FLOW_REVERSE_AUCTIONS, revAuctionMOCtoRBTC_mocV1);\n        governedRegistry.removeAddressArrayElement(MOC_FLOW_BUFFERS, rocrRewardsBuffer);\n        governedRegistry.removeAddressArrayElement(MOC_FLOW_BUFFERS, bitProRewardsBuffer);\n        governedRegistry.removeAddressArrayElement(MOC_FLOW_BUFFERS, bproRewardsBuffer);\n        governedRegistry.removeAddressArrayElement(MOC_FLOW_BUFFERS, mocRewardsBuffer);\n\n        // 14) Reset useMaxLastPublication block because DOC bucket always has a valid price(it does not use conditional price)\n        //      false: use the minimum, so operations enqueued before the oldest price are executed. New operations\n        //      have to wait until all the prices are updated\n        //      true: use the maximum, so operations enqueued before the newest price are executed. New operations\n        //      have to wait until only one price is updated\n        mocMultiCollateralGuard.setUseMaxLastPublicationBlock(false);\n\n        IReverseAuction(revAuctionDOCtoMOC_rocRewardsBuffer).setOutputAccount(mocRewardsBuffer);\n        rifCommissionSplitterV2.setAcTokenPctToRecipient1(666666666666666666);\n    }\n\n    /**\n     * @notice Adds all deployed tasks to the already-deployed TasksRunner.\n     */\n    function _addTasksToTasksRunner() internal {\n        ITasksRunner runner = ITasksRunner(tasksRunner);\n        for (uint256 i = 0; i < tasks.length; i++) {\n            runner.addTask(tasks[i]);\n        }\n    }\n\n    /**\n     * @notice Redirects the Foundation commission-splitter branches and the BTC/USD oracle branch.\n     */\n    function _rewireOracleFundingFlows() internal {\n        // RIF splitters:\n        // - RIF legs that used to pay Foundation now pay the new RIF 70/30 buffer\n        // - MOC fee-token leg on rifCommissionSplitterV2 now pays the new MOC 70/30 buffer\n        rifCommissionSplitterV3.setAcTokenAddressRecipient1(splitRifFeesToFoundationAndRifOracle);\n        rifCommissionSplitterV2.setAcTokenAddressRecipient1(splitRifFeesToFoundationAndRifOracle);\n        rifCommissionSplitterV2.setFeeTokenAddressRecipient1(splitMocFeesToFoundationAndRifOracle);\n\n        // DOC splitter:\n        // - DOC leg that used to pay Foundation now pays the new DOC 70/30 buffer\n        // - MOC fee-token leg that used to pay Foundation now pays the new MOC 70/30 buffer\n        docCommissionSplitterV2.setAcTokenAddressRecipient1(splitDocFeesToFoundationAndRifOracle);\n        docCommissionSplitterV2.setFeeTokenAddressRecipient1(splitMocFeesToFoundationAndRifOracle);\n\n        // The top-level MOC rewards buffer keeps Supporters untouched and routes its BTC/USD\n        // branch to a new child buffer that splits 90/10 between BTC/USD and TasksRunner.\n        _replaceBufferOutputAtIndex(\n            mocRewardsBuffer,\n            mocRewardsBufferBtcUsdOutputIndex,\n            btcUsdCoinPair,\n            splitMocRewardsToBtcOracleAndTasksRunner\n        );\n    }\n\n    /**\n     * @notice Applies the post-upgrade queue execution-cost configuration.\n     */\n    function _updateQueueExecutionCosts(MocQueue queue_, uint256[] storage rawExecutionCosts_) internal {\n        queue_.updateExecutionCosts(_buildQueueExecutionCosts(rawExecutionCosts_));\n    }\n\n    /**\n     * @notice Rebuilds the queue execution-cost struct from the constructor-provided values.\n     */\n    function _buildQueueExecutionCosts(\n        uint256[] storage rawExecutionCosts_\n    ) internal view returns (MocQueueExecFees.InitializeMocQueueExecCostsParams memory execCosts) {\n        require(rawExecutionCosts_.length == 10, \"queue execution costs length\");\n        execCosts = MocQueueExecFees.InitializeMocQueueExecCostsParams({\n            tcMintExecCost: rawExecutionCosts_[0],\n            tcRedeemExecCost: rawExecutionCosts_[1],\n            tpMintExecCost: rawExecutionCosts_[2],\n            tpRedeemExecCost: rawExecutionCosts_[3],\n            swapTPforTPExecCost: rawExecutionCosts_[4],\n            swapTPforTCExecCost: rawExecutionCosts_[5],\n            swapTCforTPExecCost: rawExecutionCosts_[6],\n            redeemTCandTPExecCost: rawExecutionCosts_[7],\n            mintTCandTPExecCost: rawExecutionCosts_[8],\n            priceUpdatesCost: rawExecutionCosts_[9]\n        });\n    }\n\n    /**\n     * @notice Ensures the new direct RIF/USD coin pair explicitly whitelists every direct consumer.\n     */\n    function _ensureRifOracleWhitelist(address coinPair_) internal {\n        ICoinPairPriceGovernance coinPair = ICoinPairPriceGovernance(coinPair_);\n        address infoAddr = governedRegistry.getAddress(INFO_ADDR);\n\n        _whitelistIfNeeded(coinPair, address(rifBucket));\n        _whitelistIfNeeded(coinPair, rifToRbtcPriceProvider);\n        _whitelistIfNeeded(coinPair, mocToRifPriceProvider);\n        _whitelistIfNeeded(coinPair, taskExecuteQueueV3);\n        _whitelistIfNeeded(coinPair, taskUpdateEmaV3RifBucket);\n        _whitelistIfNeeded(coinPair, infoAddr);\n    }\n\n    function _whitelistIfNeeded(ICoinPairPriceGovernance coinPair_, address account_) internal {\n        if (account_ != address(0) && !coinPair_.isPricePeekWhitelisted(account_)) {\n            coinPair_.addPricePeekWhitelist(account_);\n        }\n    }\n\n    /**\n     * @notice Only edits the RIF bucket price provider; all other Pegged Token params are read from live state.\n     */\n    function _editRifBucketPriceProvider(address priceProvider_) internal {\n        MocRC20 usdRifAddress = MocRC20(address(rifBucket.tpTokens(0)));\n        (, uint256 emaSf) = rifBucket.tpEma(0);\n\n        PeggedTokenParams memory peggedTokenParams = PeggedTokenParams({\n            priceProviderAddress: priceProvider_,\n            tpCtarg: rifBucketUsdrifTargetEma,\n            tpMintFee: rifBucket.tpMintFees(address(usdRifAddress)),\n            tpRedeemFee: rifBucket.tpRedeemFees(address(usdRifAddress)),\n            tpEma: 0,\n            tpEmaSf: emaSf\n        });\n\n        rifBucket.editPeggedToken(usdRifAddress, peggedTokenParams);\n    }\n\n    /**\n     * @notice Rebuilds current bucket params preserving every value except the fields changed by this rollout.\n     */\n    function _buildBucketParams(\n        MocOperations bucket_,\n        address rebalanceExecFeeRecipient_,\n        IPriceProvider acCoinbasePriceProvider_\n    ) internal view returns (BucketParams memory) {\n        return\n            BucketParams({\n                acCoinbasePriceProvider: acCoinbasePriceProvider_,\n                rebalanceExecFeeRecipient: rebalanceExecFeeRecipient_,\n                rtcThrld: mocMultiCollateralGuard.rtcThrld(bucket_),\n                microLiquidationThrld: mocMultiCollateralGuard.microLiquidationThrld(bucket_),\n                penaltyRate: mocMultiCollateralGuard.penaltyRate(bucket_)\n            });\n    }\n    /**\n     * @notice Replaces a known buffer output while preserving the configured split and threshold.\n     */\n    function _replaceBufferOutputAtIndex(\n        address buffer_,\n        uint256 outputIndex_,\n        address currentOutput_,\n        address nextOutput_\n    ) internal {\n        IBufferLike buffer = IBufferLike(buffer_);\n        (address output, uint256 split, , uint256 threshold) = buffer.getOutput(outputIndex_);\n        require(output == currentOutput_, \"unexpected buffer output\");\n        buffer.removeOutput(outputIndex_);\n        buffer.addOutput(payable(nextOutput_), split, threshold);\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/utils/introspection/IERC165Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/interfaces/IPriceProvider.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\n/**\n * @title IPriceProvider\n * @notice Interface for peeking the price and last publication block of a given asset\n * @dev https://github.com/money-on-chain/OMoC-Decentralized-Oracle\n */\ninterface IPriceProvider {\n    /**\n     * @notice returns the given `price` for the asset if `valid`\n     * @return price assetPrice\n     * @return valid true if the price is valid\n     */\n    function peek() external view returns (bytes32 price, bool valid);\n\n    /**\n     * @notice returns the last publication block of an asset price\n     * @dev only valid for decentralized oracles\n     * @return lastPublicationBlock\n     */\n    function getLastPublicationBlock() external view returns (uint256 lastPublicationBlock);\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/core/MocBaseBucket.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\n/* solhint-disable max-states-count */\npragma solidity 0.8.24;\n\nimport { IMocRC20 } from \"../interfaces/IMocRC20.sol\";\nimport { IPriceProvider } from \"../interfaces/IPriceProvider.sol\";\nimport { IDataProvider } from \"../interfaces/IDataProvider.sol\";\nimport { MocUpgradable } from \"../governance/MocUpgradable.sol\";\nimport { IMocQueue } from \"../interfaces/IMocQueue.sol\";\nimport { IMocMultiCollateralGuard } from \"../interfaces/IMocMultiCollateralGuard.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/**\n * @title MocBaseBucket: Moc Collateral Bag\n * @notice MocBaseBucket holds Bucket Zero state, both for the Collateral Bag and PeggedTokens Items.\n * @dev Abstracts all rw operations on the main bucket and expose all calculations relative to its state.\n */\nabstract contract MocBaseBucket is MocUpgradable {\n    // ------- Custom Errors -------\n    error MissingProviderPrice(address priceProviderAddress_);\n    error Liquidated();\n    error LowCoverage(uint256 cglb_, uint256 covThrld_);\n    error RecipientMustBeSender();\n    error OnlyMultiCollateralGuard();\n\n    // ------- Structs -------\n    struct PegContainerItem {\n        // total supply of Pegged Token\n        uint256 nTP;\n        // PegToken PriceFeed address\n        IPriceProvider priceProvider;\n    }\n\n    struct PeggedTokenIndex {\n        // Pegged Token index\n        uint256 index;\n        // true if Pegged Token exists\n        bool exists;\n    }\n\n    struct InitializeBaseBucketParams {\n        // MocQueue contract address\n        address payable mocQueueAddress;\n        // Fee Token contract address\n        address feeTokenAddress;\n        // Fee Token price provider address\n        address feeTokenPriceProviderAddress;\n        // Collateral Token contract address\n        address tcTokenAddress;\n        // Moc Fee Flow contract address\n        address mocFeeFlowAddress;\n        // moc appreciation beneficiary Address\n        address mocAppreciationBeneficiaryAddress;\n        // protected state threshold [PREC]\n        uint256 protThrld;\n        // liquidation coverage threshold [PREC]\n        uint256 liqThrld;\n        // operations fees values for each operation type\n        OperationsFeeParams operationsFeeParams;\n        // pct of the gain because Pegged Tokens devaluation that is transferred\n        // in Collateral Asset to Moc Fee Flow during the settlement [PREC]\n        uint256 successFee;\n        // pct of the gain because Pegged Tokens devaluation that is returned\n        // in Pegged Tokens to appreciation beneficiary during the settlement [PREC]\n        uint256 appreciationFactor;\n        // time between settlements\n        uint256 settlementTimeSpan;\n        // TC interest collector address\n        address tcInterestCollectorAddress;\n        // pct interest charged to TC holders on the total collateral in the protocol [PREC]\n        uint256 tcInterestRate;\n        // amount of seconds to wait for next TC interest payment\n        uint256 tcInterestPaymentTimeSpan;\n        // max absolute operation provider address:\n        //  absolute maximum transaction allowed for a certain number of time\n        //  if absoluteAccumulator is above the value provided the operation will be rejected\n        address maxAbsoluteOpProviderAddress;\n        // max operation difference provider address:\n        //  differential maximum transaction allowed for a certain number of time\n        //  if operationalDifference is above the value provided the operation will be rejected\n        address maxOpDiffProviderAddress;\n        // number of seconds that have to elapse for the linear decay factor to be 0\n        uint256 decayTimeSpan;\n        // flag to allow users operate using another address as the recipient of the tokens\n        bool allowDifferentRecipient;\n    }\n\n    struct OperationsFeeParams {\n        // additional fee pct applied on Collateral Tokens mint [PREC]\n        uint256 tcMintFee; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n        // additional fee pct applied on Collateral Tokens redeem [PREC]\n        uint256 tcRedeemFee; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n        // additional fee pct applied on swap a Pegged Token for another Pegged Token [PREC]\n        uint256 swapTPforTPFee; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n        // additional fee pct applied on swap a Pegged Token for Collateral Token [PREC]\n        uint256 swapTPforTCFee; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n        // additional fee pct applied on swap Collateral Token for a Pegged Token [PREC]\n        uint256 swapTCforTPFee; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n        // additional fee pct applied on redeem Collateral Token and Pegged Token in one operations [PREC]\n        uint256 redeemTCandTPFee; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n        // additional fee pct applied on mint Collateral Token and Pegged Token in one operation [PREC]\n        uint256 mintTCandTPFee; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n        // pct retain on fees to be re-injected as Collateral, while paying fees with AC [PREC]\n        uint256 feeRetainer;\n        // pct applied on the top of the operation`s fee when using Fee Token as fee payment method [PREC]\n        // e.g. if tcMintFee = 1%, feeTokenPct = 50% => qFeeToken = 0.5%\n        uint256 feeTokenPct;\n    }\n\n    // ------- Storage -------\n\n    // Fee Token\n    IERC20 public feeToken;\n    // Fee Token price provider\n    IPriceProvider public feeTokenPriceProvider;\n    // total amount of Collateral Asset held in the Collateral Bag\n    // WARN: On RC20 implementation, this correlates with contract acBalance\n    uint256 public nACcb;\n    // amount of Collateral Asset that the Vaults owe to the Collateral Bag\n    // this variable is not used and is reserved for a future upgrade of the protocol\n    // slither-disable-next-line constable-states\n    uint256 internal nACioucb;\n\n    // Collateral Token\n    IMocRC20 public tcToken;\n    // Collateral Token in the Collateral Bag\n    uint256 public nTCcb;\n\n    // Pegged Tokens MocRC20 addresses\n    IMocRC20[] public tpTokens;\n    // Pegged Token indexes\n    mapping(address => PeggedTokenIndex) public peggedTokenIndex;\n    // peg container\n    PegContainerItem[] public pegContainer;\n    // Pegged Token prices, at which they can be redeemed after liquidation event\n    uint256[] public tpLiqPrices;\n    // pct of the gain because Pegged Tokens devaluation that is transferred\n    // in Collateral Asset to Moc Fee Flow during the settlement [PREC]\n    uint256 public successFee;\n    // pct of the gain because Pegged Tokens devaluation that is returned\n    // in Pegged Tokens to appreciation beneficiary during the settlement [PREC]\n    uint256 public appreciationFactor;\n\n    // ------- Storage Fees -------\n\n    // pct retain on fees to be re-injected as Collateral, while paying fees with AC [PREC]\n    uint256 public feeRetainer; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n    // additional fee pct applied on Collateral Tokens mint [PREC]\n    uint256 public tcMintFee; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n    // additional fee pct applied on Collateral Tokens redeem [PREC]\n    uint256 public tcRedeemFee; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n    // additional fee pct applied on swap a Pegged Token for another Pegged Token [PREC]\n    uint256 public swapTPforTPFee; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n    // additional fee pct applied on swap a Pegged Token for Collateral Token [PREC]\n    uint256 public swapTPforTCFee; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n    // additional fee pct applied on swap Collateral Token for a Pegged Token [PREC]\n    uint256 public swapTCforTPFee; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n    // additional fee pct applied on redeem Collateral Token and Pegged Token in one operations [PREC]\n    uint256 public redeemTCandTPFee; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n    // additional fee pct applied on mint Collateral Token and Pegged Token in one operation [PREC]\n    uint256 public mintTCandTPFee; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n    // pct applied on the top of the operation`s fee when using Fee Token as fee payment method [PREC]\n    // e.g. if tcMintFee = 1%, FeeTokenPct = 50% => qFeeToken = 0.5%\n    uint256 public feeTokenPct; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n\n    // Pegged Token => addition fee pct applied on TP mint [PREC]\n    mapping(address => uint256) public tpMintFees; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n    // Pegged Token =>  addition fee pct applied on TP redeem [PREC]\n    mapping(address => uint256) public tpRedeemFees; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n\n    // Moc Fee Flow contract address\n    address public mocFeeFlowAddress;\n    // Moc appreciation beneficiary address\n    address public mocAppreciationBeneficiaryAddress;\n\n    // ------- Storage Coverage Tracking -------\n\n    // Target coverage for each Pegged Token [PREC]\n    uint256[] public tpCtarg;\n    // Coverage protected state threshold [PREC]\n    uint256 public protThrld;\n    // Coverage liquidation threshold [PREC]\n    uint256 public liqThrld;\n    // Liquidation enabled\n    bool public liqEnabled;\n    // Irreversible state, peg lost, contract is terminated and all funds can be withdrawn\n    bool public liquidated;\n    // flag to allow users operate using another address as the recipient of the tokens\n    bool internal _allowDifferentRecipient;\n\n    // ------- Storage Settlement -------\n\n    // time between settlements\n    uint256 public settlementTimeSpan;\n    // next settlement time\n    uint256 public nextSettlementTime;\n\n    // ------- Storage Queue -------\n\n    // amount of AC locked on MocQueue for pending operations\n    uint256 public qACLockedInPending;\n    // address for MocQueue contract\n    address payable public mocQueue; // cannot used MocQueue, import failed due circular reference\n\n    // ------- Storage Success Fee Tracking -------\n\n    // profit and loss in collateral asset for each Pegged Token because its devaluation [N]\n    // if it is positive it is a profit that will be distributed and reset during settlement\n    int256[] internal tpiou;\n    // Pegged Token price used at last operation(redeem or mint) [PREC]\n    uint256[] internal pACtpLstop;\n\n    // ------- Storage Flux Capacitor -------\n\n    // max absolute operation provider:\n    //  absolute maximum transaction volume allowed for a certain number of time\n    //  if absoluteAccumulator is above the value provided the operation will be rejected\n    IDataProvider public maxAbsoluteOpProvider;\n    // max operation difference provider:\n    //  differential maximum transaction volume allowed for a certain number of time\n    //  if operationalDifference is above the value provided the operation will be rejected\n    IDataProvider public maxOpDiffProvider;\n    // number of seconds that have to elapse for the linear decay factor to be 0\n    uint256 public decayTimeSpan;\n    // accumulator increased by minting and redeeming TP operations\n    uint256 public absoluteAccumulator;\n    // accumulator increased by minting and decreased by redeeming TP operations\n    int256 public differentialAccumulator;\n    // last time an operation was submitted\n    uint256 public lastOperationTimeStamp;\n\n    // ------- Storage TC Holders Interest Payment -------\n\n    // TC interest collector address\n    address public tcInterestCollectorAddress;\n    // pct interest charged to TC holders on the total collateral in the protocol [PREC]\n    uint256 public tcInterestRate;\n    // amount of seconds to wait for next TC interest payment\n    uint256 public tcInterestPaymentTimeSpan;\n    // next TC interest payment time\n    uint256 public nextTCInterestPayment;\n\n    // ------- Modifiers -------\n    /// @notice functions with this modifier reverts being in liquidated state\n    modifier notLiquidated() {\n        _checkLiquidated();\n        _;\n    }\n\n    /// @notice functions with this modifier reverts if recipient is another address and is not allowed\n    modifier checkRecipient(address sender_, address recipient_) {\n        _checkRecipient(sender_, recipient_);\n        _;\n    }\n\n    /// @notice functions with this modifier can only be called by the MultiCollateralGuard contract\n    modifier onlyMultiCollateralGuard() {\n        if (msg.sender != address(_getMocMultiCollateralGuard())) revert OnlyMultiCollateralGuard();\n        _;\n    }\n\n    // ------- Initializer -------\n    /**\n     * @notice contract initializer\n     * @param initializeBaseBucketParams_ contract initializer params\n     * @dev   mocQueueAddress address for MocQueue contract\n     *        feeTokenAddress Fee Token contract address\n     *        feeTokenPriceProviderAddress Fee Token price provider contract address\n     *        tcTokenAddress Collateral Token contract address\n     *        mocFeeFlowAddress Moc Fee Flow contract address\n     *        mocAppreciationBeneficiaryAddress Moc appreciation beneficiary address\n     *        protThrld protected coverage threshold [PREC]\n     *        liqThrld liquidation coverage threshold [PREC]\n     *        feeRetainer pct retain on fees to be re-injected as Collateral, while paying fees with AC [PREC]\n     *        tcMintFee additional fee pct applied on mint Collateral Tokens operations [PREC]\n     *        tcRedeemFee additional fee pct applied on redeem Collateral Tokens operations [PREC]\n     *        swapTPforTPFee additional fee pct applied on swap a Pegged Token for another Pegged Token [PREC]\n     *        swapTPforTCFee additional fee pct applied on swap a Pegged Token for Collateral Token [PREC]\n     *        swapTCforTPFee additional fee pct applied on swap Collateral Token for a Pegged Token [PREC]\n     *        redeemTCandTPFee additional fee pct applied on redeem Collateral Token and Pegged Token [PREC]\n     *        mintTCandTPFee additional fee pct applied on mint Collateral Token and Pegged Token [PREC]\n     *        feeTokenPct pct applied on the top of the operation`s fee when using\n     *          Fee Token as fee payment method [PREC]\n     *        successFee pct of the gain because Pegged Tokens devaluation that is transferred\n     *          in Collateral Asset to Moc Fee Flow during the settlement [PREC]\n     *        appreciationFactor pct of the gain because Pegged Tokens devaluation that is returned\n     *          in Pegged Tokens to appreciation beneficiary during the settlement [PREC]\n     *        settlementTimeSpan time between settlements\n     *        tcInterestCollectorAddress TC interest collector address\n     *        tcInterestRate pct interest charged to TC holders on the total collateral in the protocol [PREC]\n     *        tcInterestPaymentTimeSpan amount of seconds to wait for next TC interest payment\n     *        maxAbsoluteOpProviderAddress max absolute operation provider address\n     *        maxOpDiffProviderAddress max operation difference provider address\n     *        decayTimeSpan number of seconds that have to elapse for the linear decay factor to be 0\n     *        allowDifferentRecipient flag to allow users operate using another address as the recipient of the tokens\n     */\n    function __MocBaseBucket_init_unchained(\n        InitializeBaseBucketParams calldata initializeBaseBucketParams_\n    ) internal onlyInitializing {\n        mocQueue = initializeBaseBucketParams_.mocQueueAddress;\n        feeToken = IERC20(initializeBaseBucketParams_.feeTokenAddress);\n        feeTokenPriceProvider = IPriceProvider(initializeBaseBucketParams_.feeTokenPriceProviderAddress);\n        tcToken = IMocRC20(initializeBaseBucketParams_.tcTokenAddress);\n        mocFeeFlowAddress = initializeBaseBucketParams_.mocFeeFlowAddress;\n        mocAppreciationBeneficiaryAddress = initializeBaseBucketParams_.mocAppreciationBeneficiaryAddress;\n        protThrld = initializeBaseBucketParams_.protThrld;\n        liqThrld = initializeBaseBucketParams_.liqThrld;\n        tcMintFee = initializeBaseBucketParams_.operationsFeeParams.tcMintFee;\n        tcRedeemFee = initializeBaseBucketParams_.operationsFeeParams.tcRedeemFee;\n        swapTPforTPFee = initializeBaseBucketParams_.operationsFeeParams.swapTPforTPFee;\n        swapTPforTCFee = initializeBaseBucketParams_.operationsFeeParams.swapTPforTCFee;\n        swapTCforTPFee = initializeBaseBucketParams_.operationsFeeParams.swapTCforTPFee;\n        redeemTCandTPFee = initializeBaseBucketParams_.operationsFeeParams.redeemTCandTPFee;\n        mintTCandTPFee = initializeBaseBucketParams_.operationsFeeParams.mintTCandTPFee;\n        feeRetainer = initializeBaseBucketParams_.operationsFeeParams.feeRetainer;\n        feeTokenPct = initializeBaseBucketParams_.operationsFeeParams.feeTokenPct;\n        successFee = initializeBaseBucketParams_.successFee;\n        appreciationFactor = initializeBaseBucketParams_.appreciationFactor;\n        settlementTimeSpan = initializeBaseBucketParams_.settlementTimeSpan;\n        tcInterestCollectorAddress = initializeBaseBucketParams_.tcInterestCollectorAddress;\n        tcInterestRate = initializeBaseBucketParams_.tcInterestRate;\n        tcInterestPaymentTimeSpan = initializeBaseBucketParams_.tcInterestPaymentTimeSpan;\n        maxAbsoluteOpProvider = IDataProvider(initializeBaseBucketParams_.maxAbsoluteOpProviderAddress);\n        maxOpDiffProvider = IDataProvider(initializeBaseBucketParams_.maxOpDiffProviderAddress);\n        decayTimeSpan = initializeBaseBucketParams_.decayTimeSpan;\n        lastOperationTimeStamp = block.timestamp;\n        unchecked {\n            nextSettlementTime = block.timestamp + initializeBaseBucketParams_.settlementTimeSpan;\n            nextTCInterestPayment = block.timestamp + initializeBaseBucketParams_.tcInterestPaymentTimeSpan;\n        }\n        liquidated = false;\n        liqEnabled = false;\n        _allowDifferentRecipient = initializeBaseBucketParams_.allowDifferentRecipient;\n    }\n\n    // ------- Internal Functions -------\n\n    /**\n     * reverts if in liquidated state\n     */\n    function _checkLiquidated() internal view {\n        if (liquidated) revert Liquidated();\n    }\n\n    /**\n     * reverts if recipient is another address and is not allowed\n     */\n    function _checkRecipient(address sender_, address recipient_) internal view {\n        if (!_allowDifferentRecipient && sender_ != recipient_) revert RecipientMustBeSender();\n    }\n\n    /**\n     * @notice Adds Collateral Asset to the Bucket\n     * @param qAC_ amount of Collateral Asset to add\n     */\n    function _depositAC(uint256 qAC_) internal {\n        nACcb += qAC_;\n    }\n\n    /**\n     * @notice Adds Collateral Token and Collateral Asset to the Bucket\n     * @param qTC_ amount of Collateral Token to add\n     * @param qAC_ amount of Collateral Asset to add\n     */\n    function _depositTC(uint256 qTC_, uint256 qAC_) internal {\n        nTCcb += qTC_;\n        _depositAC(qAC_);\n    }\n\n    /**\n     * @notice Subtracts Collateral Token and Collateral Asset from the Bucket\n     * @param qTC_ amount of Collateral Token to subtract\n     * @param qAC_ amount of Collateral Asset to subtract\n     */\n    function _withdrawTC(uint256 qTC_, uint256 qAC_) internal {\n        nTCcb -= qTC_;\n        nACcb -= qAC_;\n    }\n\n    /**\n     * @notice Adds Pegged Token and Collateral Asset to the Bucket\n     * @param i_ Pegged Token index\n     * @param qTP_ amount of Pegged Token to add\n     * @param qAC_ amount of Collateral Asset to add\n     */\n    function _depositTP(uint256 i_, uint256 qTP_, uint256 qAC_) internal {\n        pegContainer[i_].nTP += qTP_;\n        _depositAC(qAC_);\n    }\n\n    /**\n     * @notice Subtracts Pegged Token and Collateral Asset from the Bucket\n     * @param i_ Pegged Token index\n     * @param qTP_ amount of Pegged Token to subtract\n     * @param qAC_ amount of Collateral Asset to subtract\n     */\n    function _withdrawTP(uint256 i_, uint256 qTP_, uint256 qAC_) internal {\n        pegContainer[i_].nTP -= qTP_;\n        nACcb -= qAC_;\n    }\n\n    /**\n     * @notice Adds Pegged Token and Collateral Asset to the Bucket and mints `qTP_` for Pegged Token `i_`\n     * @param i_ Pegged Token index\n     * @param qTP_ amount of Pegged Token to add\n     * @param qAC_ amount of Collateral Asset to add\n     * @param recipient_ the account to mint tokens to\n     */\n    function _depositAndMintTP(uint256 i_, uint256 qTP_, uint256 qAC_, address recipient_) internal {\n        // add qTP and qAC to the Bucket\n        _depositTP(i_, qTP_, qAC_);\n        // mint qTP to the recipient\n        _mintToken(tpTokens[i_], recipient_, qTP_);\n    }\n\n    /**\n     * @notice subtracts Pegged Token and Collateral Asset from the Bucket and burns `qTP_` for Pegged Token `i_`\n     * @param i_ Pegged Token index\n     * @param qTP_ amount of Pegged Token to subtract\n     * @param qAC_ amount of Collateral Asset to subtract\n     */\n    function _withdrawAndBurnTP(uint256 i_, uint256 qTP_, uint256 qAC_) internal {\n        // sub qTP and qAC from the Bucket\n        _withdrawTP(i_, qTP_, qAC_);\n        // burn the qTP previously locked from the user\n        _burnToken(tpTokens[i_], qTP_);\n    }\n\n    /**\n     * @notice Adds Collateral Token and Collateral Asset to the Bucket and mints qTCtoMint\n     * @param qTC_ amount of Collateral Token to add\n     * @param qAC_ amount of Collateral Asset to add\n     * @param recipient_ the account to mint tokens to\n     */\n    function _depositAndMintTC(uint256 qTC_, uint256 qAC_, address recipient_) internal {\n        // add qTC to the Bucket\n        _depositTC(qTC_, qAC_);\n        // mint qTC to the recipient\n        _mintToken(tcToken, recipient_, qTC_);\n    }\n\n    /**\n     * @notice Subtracts Collateral Token and Collateral Asset from the Bucket and burns `qTC_`\n     * @param qTC_ amount of Collateral Token to subtract\n     * @param qAC_ amount of Collateral Asset to subtract\n     */\n    function _withdrawAndBurnTC(uint256 qTC_, uint256 qAC_) internal {\n        // sub qTC and qAC from the Bucket\n        _withdrawTC(qTC_, qAC_);\n        // burn the qTC previously locked from the user\n        _burnToken(tcToken, qTC_);\n    }\n\n    /**\n     * @notice mint tokens\n     * @param token_ IMocRC20 token to mint\n     * @param recipient_ address who receives the tokens\n     * @param amount_ amount of tokens to mint\n     */\n    function _mintToken(IMocRC20 token_, address recipient_, uint256 amount_) internal {\n        // slither-disable-next-line unused-return\n        token_.mint(recipient_, amount_);\n    }\n\n    /**\n     * @notice burn tokens\n     * @param token_ IMocRC20 token to burn\n     * @param amount_ amount of tokens to burn\n     */\n    function _burnToken(IMocRC20 token_, uint256 amount_) internal {\n        // slither-disable-next-line unused-return\n        token_.burn(address(this), amount_);\n    }\n\n    /**\n     * @notice gets MocMultiCollateralGuard contract\n     */\n    function _getMocMultiCollateralGuard() internal view returns (IMocMultiCollateralGuard) {\n        return IMocMultiCollateralGuard(IMocQueue(mocQueue).mocMultiCollateralGuard());\n    }\n\n    /**\n     * @notice get amount of Collateral Asset available considering how many are locked by Pegged Token adjusted by EMA\n     * @param ctargemaCA_ target coverage adjusted by the moving average of the value of the Collateral Asset [PREC]\n     * @param lckAC_ amount of Collateral Asset locked by Pegged Token [N]\n     * @param nACgain_ amount of collateral asset to be distributed during settlement [N]\n     * @return lckACemaAdjusted [PREC]\n     */\n    function _getLckACemaAdjusted(\n        uint256 ctargemaCA_,\n        uint256 lckAC_,\n        uint256 nACgain_\n    ) internal view returns (int256 lckACemaAdjusted) {\n        // [PREC] = [N] * [PREC] - [PREC] * [N]\n        return int256(_getTotalACavailable(nACgain_) * PRECISION) - int256(ctargemaCA_ * lckAC_);\n    }\n\n    /**\n     * @notice get amount of Collateral Token available to redeem\n     * @param ctargemaCA_ target coverage adjusted by the moving average of the value of the Collateral Asset [PREC]\n     * @param lckAC_ amount of Collateral Asset locked by Pegged Token [N]\n     * @param nACgain_ amount of collateral asset to be distributed during settlement [N]\n     * @return tcAvailableToRedeem [N]\n     */\n    function _getTCAvailableToRedeem(\n        uint256 ctargemaCA_,\n        uint256 lckAC_,\n        uint256 nACgain_\n    ) internal view virtual returns (uint256 tcAvailableToRedeem) {\n        // [PREC]\n        int256 lckACemaAdjusted = _getLckACemaAdjusted(ctargemaCA_, lckAC_, nACgain_);\n        if (lckACemaAdjusted <= 0) return 0;\n        // [N] = [PREC] / [PREC]\n        return uint256(lckACemaAdjusted) / _getPTCac(lckAC_, nACgain_);\n    }\n\n    /**\n     * @notice get signed amount of Pegged Token available to mint\n     * @dev negative value is needed for multi collateral implementation\n     * @param ctargemaCA_ target coverage adjusted by the moving average of the value of the Collateral Asset\n     * @param ctargemaTP_ target coverage adjusted by the moving average of the value of a Pegged Token\n     * @param pACtp_ Collateral Asset price in amount of Pegged Token [PREC]\n     * @param lckAC_ amount of Collateral Asset locked by Pegged Token [N]\n     * @param nACgain_ amount of collateral asset to be distributed during settlement [N]\n     * @return tpAvailableToMint [N]\n     */\n    function _getTPAvailableToMintSigned(\n        uint256 ctargemaCA_,\n        uint256 ctargemaTP_,\n        uint256 pACtp_,\n        uint256 lckAC_,\n        uint256 nACgain_\n    ) internal view returns (int256 tpAvailableToMint) {\n        int256 lckACemaAdjusted = _getLckACemaAdjusted(ctargemaCA_, lckAC_, nACgain_);\n        // [N] = [PREC] * [PREC] / ([PREC]) * [PREC])\n        return (lckACemaAdjusted * int256(pACtp_)) / int256((ctargemaTP_ - ONE) * PRECISION);\n    }\n\n    /**\n     * @notice evaluates whether or not the coverage is over the cThrld_, reverts if below\n     * @param cThrld_ coverage threshold to check for [PREC]\n     * @param pACtps_ array of all AC prices for each TP, with [PREC]\n     * @return lckAC amount of Collateral Asset locked by Pegged Tokens [PREC]\n     * @return nACgain amount of collateral asset to be distributed during settlement [N]\n     */\n    function _evalCoverage(\n        uint256 cThrld_,\n        uint256[] memory pACtps_\n    ) internal view returns (uint256 lckAC, uint256 nACgain) {\n        (lckAC, nACgain) = _calcLckACandACgain(pACtps_);\n        uint256 cglb = _getCglb(lckAC, nACgain);\n        // check if coverage is above the given threshold\n        if (cglb <= cThrld_) revert LowCoverage(cglb, cThrld_);\n    }\n\n    /**\n     * @notice indicates whether or not PnL should be tracked\n     * @dev if both successFee and appreciationFactor are zero, there is no point\n     * to track and store PnL, so these features are considered disabled.\n     */\n    function _isPnLTrackingEnabled() internal view returns (bool) {\n        return (successFee != 0 || appreciationFactor != 0);\n    }\n\n    /**\n     * @notice updates Pegged Token P&L and last operation price\n     * @param i_ Pegged Token index\n     * @param pACtp_ Pegged Token price [PREC]\n     */\n    function _updateTPtracking(uint256 i_, uint256 pACtp_) internal {\n        if (_isPnLTrackingEnabled()) {\n            tpiou[i_] += _calcOtfPnLTP(i_, pACtp_);\n            pACtpLstop[i_] = pACtp_;\n        }\n    }\n\n    /**\n     * @notice calculates on the fly Pegged Token P&L\n     * @param i_ Pegged Token index\n     * @param pACtp_ Pegged Token price [PREC]\n     * @return otfPnLtp [N]\n     */\n    function _calcOtfPnLTP(uint256 i_, uint256 pACtp_) internal view returns (int256 otfPnLtp) {\n        // [PREC] = [N] * [PREC]\n        uint256 nTP = pegContainer[i_].nTP * PRECISION;\n        // [N] = [PREC] / [PREC] - [PREC] / [PREC]\n        return int256(nTP / pACtpLstop[i_]) - int256(nTP / pACtp_);\n    }\n\n    /**\n     * @notice gets accumulated Pegged Token P&L\n     * @param i_ Pegged Token index\n     * @param pACtp_ Pegged Token price [PREC]\n     * @return tpGain amount of Pegged Token to be minted during settlement [N]\n     * @return adjPnLtpi total amount of P&L in Collateral Asset [N]\n     */\n    function _getPnLTP(uint256 i_, uint256 pACtp_) internal view returns (uint256 tpGain, uint256 adjPnLtpi) {\n        if (_isPnLTrackingEnabled()) {\n            // [N] = [N] + [N]\n            int256 adjPnLtpiAux = tpiou[i_] + _calcOtfPnLTP(i_, pACtp_);\n            if (adjPnLtpiAux > 0) {\n                adjPnLtpi = uint256(adjPnLtpiAux);\n                // [N] = (([PREC] * [PREC] / [PREC]) * [N]) / [PREC]\n                tpGain = _mulPrec(_mulPrec(appreciationFactor, pACtp_), adjPnLtpi);\n            }\n        }\n    }\n\n    /**\n     * @notice get amount of Collateral Asset locked by Pegged Token and\n     *  amount of collateral asset to be distributed during settlement\n     * @return lckAC [N]\n     * @return nACgain [N]\n     */\n    function _getLckACandACgain(uint256[] memory pACtps_) internal view returns (uint256 lckAC, uint256 nACgain) {\n        return _calcLckACandACgain(pACtps_);\n    }\n\n    /**\n     * @notice calculates the amount of Collateral Asset locked by Pegged Token and\n     *  amount of collateral asset to be distributed during settlement\n     * @param pACtps_ array of all AC prices for each TP, with [PREC]\n     * @return lckAC [N]\n     * @return nACgain [N]\n     */\n    function _calcLckACandACgain(uint256[] memory pACtps_) internal view returns (uint256 lckAC, uint256 nACgain) {\n        uint256 pegAmount = pegContainer.length;\n        for (uint256 i = 0; i < pegAmount; i = unchecked_inc(i)) {\n            uint256 pACtp = pACtps_[i];\n            (uint256 tpGain, uint256 adjPnLtpi) = _getPnLTP(i, pACtp);\n            // [N] = ([N] + [N]) * [PREC] / [PREC]\n            lckAC += _divPrec(pegContainer[i].nTP + tpGain, pACtp);\n            nACgain += adjPnLtpi;\n        }\n        // [N] = [N] * [PREC] / [PREC]\n        nACgain = _mulPrec(nACgain, successFee);\n        return (lckAC, nACgain);\n    }\n\n    /**\n     * @notice get total Collateral Asset available\n     * @param nACgain_ amount of collateral asset to be distributed during settlement [N]\n     * @return totalACavailable [N]\n     */\n    function _getTotalACavailable(uint256 nACgain_) internal view returns (uint256 totalACavailable) {\n        // [N] = [N] - [N]\n        return nACcb - nACgain_;\n    }\n\n    /**\n     * @notice get Collateral Token price\n     * @param lckAC_ amount of Collateral Asset locked by Pegged Token [N]\n     * @param nACgain_ amount of collateral asset to be distributed during settlement [N]\n     * @return pTCac [PREC]\n     */\n    function _getPTCac(uint256 lckAC_, uint256 nACgain_) internal view returns (uint256 pTCac) {\n        // slither-disable-next-line incorrect-equality\n        if (nTCcb == 0) return ONE;\n        // [PREC] = ([N] - [N]) * [PREC]) / [N]\n        return _divPrec((_getTotalACavailable(nACgain_) - lckAC_), nTCcb);\n    }\n\n    /**\n     * @notice get bucket global coverage\n     * @param lckAC_ amount of Collateral Asset locked by Pegged Token [N]\n     * @param nACgain_ amount of collateral asset to be distributed during settlement [N]\n     * @return cglob [PREC]\n     */\n    function _getCglb(uint256 lckAC_, uint256 nACgain_) internal view returns (uint256 cglob) {\n        // slither-disable-next-line incorrect-equality\n        if (lckAC_ == 0) return UINT256_MAX;\n        // [PREC] = [N] * [PREC] / [N]\n        return _divPrec(_getTotalACavailable(nACgain_), lckAC_);\n    }\n\n    function _tpi(address tpAddress) internal view returns (uint256) {\n        PeggedTokenIndex storage ptIndex = peggedTokenIndex[tpAddress];\n        if (!ptIndex.exists) revert InvalidAddress();\n        return ptIndex.index;\n    }\n\n    // ------- Public Functions -------\n\n    /**\n     * @notice If liquidation is enabled, verifies if forced liquidation has been\n     * reached, checking if globalCoverage <= liquidation\n     * @return true if liquidation state is reached, false otherwise\n     */\n    function isLiquidationReached() public view returns (bool) {\n        (uint256 lckAC, uint256 nACgain) = _getLckACandACgain(_getPACtps());\n        uint256 cglb = _getCglb(lckAC, nACgain);\n        return cglb <= liqThrld;\n    }\n\n    /**\n     * @notice get how many Pegged Token equal 1 Collateral Asset\n     * @param tp_ Pegged Token address\n     * @return price [PREC]\n     */\n    function getPACtp(address tp_) external view virtual returns (uint256) {\n        return _getPACtp(_tpi(tp_));\n    }\n\n    /**\n     * @notice return current amount of Tps\n     */\n    function getTpAmount() external view returns (uint256) {\n        return tpTokens.length;\n    }\n\n    // ------- Internal Functions -------\n\n    /**\n     * @notice get how many Pegged Token equal 1 Collateral Asset\n     * @param i_ Pegged Token index\n     * @return price [PREC]\n     */\n    function _getPACtp(uint256 i_) internal view returns (uint256) {\n        IPriceProvider priceProvider = pegContainer[i_].priceProvider;\n        (uint256 price, bool has) = _peekPrice(priceProvider);\n        if (!has) revert MissingProviderPrice(address(priceProvider));\n        return price;\n    }\n\n    /**\n     * @notice ask to a price provider for its token price\n     * @dev saves some contract size by using this function instead of calling the external directly\n     * @param priceProvider_ Pegged Token index\n     * @return price casted to uint256 [PREC]\n     * @return has true if has a valid price\n     */\n    function _peekPrice(IPriceProvider priceProvider_) internal view returns (uint256, bool) {\n        (bytes32 price, bool has) = priceProvider_.peek();\n        return (uint256(price), has);\n    }\n\n    /**\n     * @notice gets all TP prices\n     * @return pACtps All tps prices [PREC]\n     */\n    function _getPACtps() internal view returns (uint256[] memory pACtps) {\n        uint256 pegAmount = pegContainer.length;\n        pACtps = new uint256[](pegAmount);\n        for (uint256 i = 0; i < pegAmount; i = unchecked_inc(i)) {\n            pACtps[i] = _getPACtp(i);\n        }\n    }\n\n    // ------- Only Authorized Changer Functions -------\n\n    /**\n     * @notice sets operations fees values for each operation type\n     */\n    function setOperationsFee(OperationsFeeParams calldata operationsFeeParams_) public onlyAuthorizedChanger {\n        tcMintFee = operationsFeeParams_.tcMintFee;\n        tcRedeemFee = operationsFeeParams_.tcRedeemFee;\n        swapTPforTPFee = operationsFeeParams_.swapTPforTPFee;\n        swapTPforTCFee = operationsFeeParams_.swapTPforTCFee;\n        swapTCforTPFee = operationsFeeParams_.swapTCforTPFee;\n        redeemTCandTPFee = operationsFeeParams_.redeemTCandTPFee;\n        mintTCandTPFee = operationsFeeParams_.mintTCandTPFee;\n        feeRetainer = operationsFeeParams_.feeRetainer;\n        feeTokenPct = operationsFeeParams_.feeTokenPct;\n    }\n\n    /**\n     * @dev sets Moc Fee Flow contract address\n     * @param mocFeeFlowAddress_ moc Fee Flow new contract address\n     */\n    function setMocFeeFlowAddress(address mocFeeFlowAddress_) external onlyAuthorizedChanger {\n        // slither-disable-next-line missing-zero-check\n        mocFeeFlowAddress = mocFeeFlowAddress_;\n    }\n\n    /**\n     * @dev sets Fee Token contract and price provider contract addresses\n     * @param mocFeeTokenAddress_ Fee Token new contract address\n     * @param mocFeeTokenPriceProviderAddress_ Fee Token price provider new contract address\n     */\n    function setFeeTokenParams(\n        address mocFeeTokenAddress_,\n        address mocFeeTokenPriceProviderAddress_\n    ) external onlyAuthorizedChanger {\n        // slither-disable-next-line missing-zero-check\n        feeToken = IERC20(mocFeeTokenAddress_);\n        // slither-disable-next-line missing-zero-check\n        feeTokenPriceProvider = IPriceProvider(mocFeeTokenPriceProviderAddress_);\n    }\n\n    /**\n     * @dev sets the coverage thresholds configuration params\n     * @param protThrld_ coverage protected state threshold [PREC]\n     * @param liqThrld_ liquidation threshold\n     */\n    function setCoverageThresholds(uint256 protThrld_, uint256 liqThrld_) external onlyAuthorizedChanger {\n        protThrld = protThrld_;\n        liqThrld = liqThrld_;\n    }\n\n    /**\n     * @dev enables and disables the liquidation mechanism.\n     * @param liqEnabled_ is liquidation enabled\n     */\n    function setLiqEnabled(bool liqEnabled_) external onlyAuthorizedChangerOrPauser {\n        liqEnabled = liqEnabled_;\n    }\n\n    /**\n     * @notice sets success Fee and appreciation Factor values.\n     * @dev if P&L tracking was disabled (both values in zero) and it's being activited, pACtpLstop values\n     * get reseted for each TP.\n     * @param successFee_ pct of the gain because Pegged Tokens devaluation that is\n     * transferred in Collateral Asset to Moc Fee Flow during the settlement [PREC]\n     * @param appreciationFactor_ pct of the gain because Pegged Tokens devaluation that is returned\n     * in Pegged Tokens to appreciation beneficiary during the settlement [PREC]\n     * @param mocAppreciationBeneficiaryAddress_ moc Appreciation Beneficiary new address\n     */\n    function setSuccessFeeParams(\n        uint256 successFee_,\n        uint256 appreciationFactor_,\n        address mocAppreciationBeneficiaryAddress_\n    ) external onlyAuthorizedChanger {\n        // If PnLTracking was disabled, we reset last Oepration pACtp to avoid incorrect pnl calculations\n        if (!_isPnLTrackingEnabled()) {\n            uint256 pegAmount = pegContainer.length;\n            for (uint256 i = 0; i < pegAmount; i = unchecked_inc(i)) {\n                pACtpLstop[i] = _getPACtp(i);\n            }\n        }\n        successFee = successFee_;\n        appreciationFactor = appreciationFactor_;\n        // slither-disable-next-line missing-zero-check\n        mocAppreciationBeneficiaryAddress = mocAppreciationBeneficiaryAddress_;\n    }\n\n    /**\n     * @dev sets TC interest params\n     * @param tcInterestCollectorAddress_ TC interest collector address\n     * @param tcInterestRate_ pct interest charged to TC holders on the total collateral in the protocol [PREC]\n     * @param tcInterestPaymentTimeSpan_ amount of seconds to wait for next TC interest payment\n     * @dev nextTCInterestPayment is not automatically updated, you have to wait until next\n     *  interest payment to be made : nextTCInterestPayment = block.timestamp + tcInterestPaymentTimeSpan\n     */\n    function setTCInterestParams(\n        address tcInterestCollectorAddress_,\n        uint256 tcInterestRate_,\n        uint256 tcInterestPaymentTimeSpan_\n    ) external onlyAuthorizedChanger {\n        // slither-disable-next-line missing-zero-check\n        tcInterestCollectorAddress = tcInterestCollectorAddress_;\n        // max interest rate allowed == 1%\n        if (tcInterestRate_ > PRECISION / 100) revert InvalidValue();\n        tcInterestRate = tcInterestRate_;\n        tcInterestPaymentTimeSpan = tcInterestPaymentTimeSpan_;\n    }\n\n    /**\n     * @param settlementTimeSpan_ time between settlements\n     * @dev settlementTimeSpan is not automatically updated, you have to wait until next\n     * settlement to be made : nextSettlementTime = block.timestamp + settlementTimeSpan\n     **/\n    function setSettlementTimeSpan(uint256 settlementTimeSpan_) external onlyAuthorizedChanger {\n        settlementTimeSpan = settlementTimeSpan_;\n    }\n\n    /**\n     * @dev sets flux capacitor providers addresses\n     * @param maxAbsoluteOpProviderAddress_ max absolute operation provider address\n     * @param maxOpDiffProviderAddress_ max operation difference provider address\n     * @param decayTimeSpan_ flux capacitor decay time span\n     */\n    function setFluxCapacitorParams(\n        address maxAbsoluteOpProviderAddress_,\n        address maxOpDiffProviderAddress_,\n        uint256 decayTimeSpan_\n    ) external onlyAuthorizedChanger {\n        // slither-disable-next-line missing-zero-check\n        maxAbsoluteOpProvider = IDataProvider(maxAbsoluteOpProviderAddress_);\n        // slither-disable-next-line missing-zero-check\n        maxOpDiffProvider = IDataProvider(maxOpDiffProviderAddress_);\n        // slither-disable-next-line missing-zero-check\n        decayTimeSpan = decayTimeSpan_;\n    }\n\n    /**\n     * @dev sets Moc Queue contract address\n     * @param mocQueueAddress_ Moc queue new contract address\n     */\n    function setMocQueue(address payable mocQueueAddress_) external onlyAuthorizedChanger {\n        // slither-disable-next-line missing-zero-check\n        mocQueue = mocQueueAddress_;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/v1/TaskSettlementV1.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../ITask.sol\";\n\n/**\n * @title TaskSettlementV1\n * @notice This contract implements a task that runs settlement for the Moc contract.\n */\ncontract TaskSettlementV1 is ITask {\n    uint256 public constant STEPS = 20;\n    IMocV1 public immutable mocV1;\n\n    /**\n     * @notice Constructor\n     * @param mocV1_ The address of the Moc contract.\n     */\n    constructor(address mocV1_) {\n        mocV1 = IMocV1(mocV1_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() external view returns (bool) {\n        IMocV1 moc = mocV1;\n        if (moc.paused()) return false;\n        return moc.isSettlementEnabled();\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        mocV1.runSettlement(STEPS);\n    }\n}\n\ninterface IMocV1 {\n    function paused() external view returns (bool);\n    function isSettlementEnabled() external view returns (bool);\n    function runSettlement(uint256 steps) external;\n}\n"},{"file_path":"npm/price-oracle-interfaces@0.1.0/contracts/interfaces/IMocState.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\n/**\n * @notice Interface for MocState price providers relevant methods\n */\ninterface IMocState {\n  enum States {\n    // State 0\n    Liquidated,\n    // State 1\n    BProDiscount,\n    // State 2\n    BelowCobj,\n    // State 3\n    AboveCobj\n  }\n\n  function state() external view returns (States);\n\n  // Relation between DOC and dollar\n  function peg() external view returns (uint256);\n\n  /**\n   * @dev BPro USD PRICE\n   * @return the BPro USD Price [using mocPrecision]\n   */\n  function bproUsdPrice() external view returns (uint256);\n\n  /**\n   * @dev BTC price of BPro\n   * @return the BPro Tec Price [using reservePrecision]\n   */\n  function bproTecPrice() external view returns (uint256);\n\n  /**\n   * @dev Gets the BTCPriceProviderAddress\n   * @return btcPriceProvider blocks there are in a day\n   **/\n  function getBtcPriceProvider() external view returns (address);\n\n  /**\n    @dev All docs in circulation\n  */\n  function docTotalSupply() external view returns (uint256);\n\n  /**\n   @dev return the value of the protected threshold configuration param\n   @return protected threshold, currently 1.5\n  */\n  function getProtected() external view returns (uint256);\n\n  function getInrateBag(bytes32 bucket) external view returns (uint256);\n\n  function rbtcInSystem() external view returns (uint256);\n\n  function getBucketNBTC(bytes32 bucket) external view returns (uint256);\n\n  function getBucketNBPro(bytes32 bucket) external view returns (uint256);\n\n  function getBucketNDoc(bytes32 bucket) external view returns (uint256);\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/interfaces/IMocSwapper.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\ninterface IMocSwapper {\n    error MissingProviderData(address dataProviderAddress_);\n\n    /**\n     * @notice wrap coinbase and swap it for another RC20 using exact input\n     * @param tokenOut_ RC20 token to receive\n     * @param amountOutMin_ minimum amount of tokens to receive\n     * @param recipient_ address who receives the tokens\n     * @return amountOut amount of RC20 tokens received\n     */\n    function swapCoinbase(\n        address tokenOut_,\n        uint256 amountOutMin_,\n        address recipient_\n    ) external payable returns (uint256 amountOut);\n\n    /**\n     * @notice wrap coinbase and swap it for another RC20 using exact output\n     * @param tokenOut_ RC20 token to receive\n     * @param amountOut_ amount of tokens to receive in the swap\n     * @param recipient_ address who receives the tokens\n     * @return amountIn amount of RC20 tokens spent\n     */\n    function swapCoinbaseExactOutput(\n        address tokenOut_,\n        uint256 amountOut_,\n        address recipient_\n    ) external payable returns (uint256 amountIn);\n\n    /**\n     * @notice swap RC20 token using exact input\n     * @param tokenIn_ RC20 token to send\n     * @param tokenOut_ token to receive. If address(0), unwrap it and send coinbase to the `recipient_`\n     * @param amountIn_ amount of tokens to swap\n     * @param amountOutMin_ minimum amount of tokens to receive\n     * @param recipient_ address who receives the tokens\n     * @return amountOut amount of RC20 tokens or coinbase received\n     */\n    function swapRC20(\n        address tokenIn_,\n        address tokenOut_,\n        uint256 amountIn_,\n        uint256 amountOutMin_,\n        address recipient_\n    ) external returns (uint256 amountOut);\n\n    /**\n     * @notice swap RC20 token using exact output\n     * @param tokenIn_ RC20 token to send\n     * @param tokenOut_ token to receive. If address(0), unwrap it and send coinbase to the `recipient_`\n     * @param amountOut_ amount of tokens to receive in the swap\n     * @param amountInMax_ maximum amount of tokens to spend\n     * @param recipient_ address who receives the tokens\n     * @return amountIn amount of RC20 tokens or coinbase spent\n     */\n    function swapRC20ExactOutput(\n        address tokenIn_,\n        address tokenOut_,\n        uint256 amountOut_,\n        uint256 amountInMax_,\n        address recipient_\n    ) external returns (uint256 amountIn);\n\n    /**\n     * @notice get the safe maximum amount of tokens to swap\n     * @dev this function is used to prevent critical losses by a pool liquidity manipulation\n     * @param tokenIn_ token to send\n     * @param tokenOut_ token to receive\n     * @return maxAmountToSwap maximum amount of tokens to swap\n     */\n    function getSafeMaxAmountToSwap(\n        address tokenIn_,\n        address tokenOut_\n    ) external view returns (uint256 maxAmountToSwap);\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/token/ERC20/extensions/IERC20PermitUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/v3/TaskRefreshACBalanceV3.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../ITask.sol\";\nimport { MocOperations } from \"@moc/moc-main/contracts/core/MocOperations.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/**\n * @title TaskRefreshACBalanceV3\n * @notice This contract implements a task that refreshes the AC balance in the Moc contract.\n */\ncontract TaskRefreshACBalanceV3 is ITask {\n    error TaskNotAvailable();\n\n    MocOperations public immutable moc;\n    uint256 public immutable balanceThreshold;\n\n    /**\n     * @notice Constructor\n     * @param moc_ The address of the Moc contract.\n     * @param balanceThreshold_ The threshold for the unaccounted AC balance to trigger the task.\n     */\n    constructor(address moc_, uint256 balanceThreshold_) {\n        moc = MocOperations(moc_);\n        balanceThreshold = balanceThreshold_;\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() public view returns (bool) {\n        MocOperations mocOp = moc;\n        address acToken = mocOp.acToken();\n        uint256 unaccountedAcBalance = IERC20(acToken).balanceOf(address(mocOp)) -\n            mocOp.nACcb() -\n            mocOp.qACLockedInPending();\n        return (unaccountedAcBalance > balanceThreshold);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        moc.refreshACBalance();\n    }\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/multiCollateral/swapper/MocSwapperV3.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocUpgradable } from \"../../governance/MocUpgradable.sol\";\nimport { IMocSwapper } from \"../../interfaces/IMocSwapper.sol\";\nimport { IWrapper } from \"../../interfaces/IWrapper.sol\";\nimport { IV3SwapRouter } from \"@uniswap/swap-router-contracts/contracts/interfaces/IV3SwapRouter.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { IDataProvider } from \"../../interfaces/IDataProvider.sol\";\n\n/**\n * @title MocSwapperV3\n * @notice MocSwapper component to swap tokens using uniswapV3 protocol\n *\n */\ncontract MocSwapperV3 is IMocSwapper, MocUpgradable {\n    address private constant COINBASE = address(0);\n    // ------- Custom Errors -------\n    error CoinbaseTransferFailed();\n    error PartialSwap();\n\n    // ------- Storage -------\n    // uniswapV3 router contracts\n    IV3SwapRouter public swapRouter;\n    // coinbase RC20 wrapper. Used to swap coinbase on the exchange\n    IWrapper public coinbaseWrapper;\n    // swap fee for the exchange pool\n    mapping(address tokenIn => mapping(address tokenOut => uint24 fee)) public fees;\n    // this is used to limit the amount of tokens that can be swapped in a single operation\n    mapping(address tokenIn => mapping(address tokenOut => IDataProvider maxAmountToSwapProvider))\n        public maxAmountToSwapProviders;\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    /**\n     * @notice contract initializer\n     * @param governorAddress_ address of the governor contract\n     * @param pauserAddress_ address of the pauser contract\n     * @param swapRouter_ address of the uniswapV3 router\n     * @param coinbaseWrapper_ address of the coinbase wrapper contract\n     */\n    function initialize(\n        address governorAddress_,\n        address pauserAddress_,\n        address swapRouter_,\n        address coinbaseWrapper_\n    ) external initializer {\n        __MocUpgradable_init(governorAddress_, pauserAddress_);\n        swapRouter = IV3SwapRouter(swapRouter_);\n        coinbaseWrapper = IWrapper(coinbaseWrapper_);\n    }\n\n    /**\n     * @inheritdoc IMocSwapper\n     */\n    function getSafeMaxAmountToSwap(address tokenIn_, address tokenOut_) public view returns (uint256) {\n        (bytes32 maxAmountToSwap, bool has) = maxAmountToSwapProviders[tokenIn_][tokenOut_].peek();\n        if (!has) revert MissingProviderData(address(maxAmountToSwapProviders[tokenIn_][tokenOut_]));\n        return uint256(maxAmountToSwap);\n    }\n\n    /**\n     * @inheritdoc IMocSwapper\n     */\n    function swapCoinbase(\n        address tokenOut_,\n        uint256 amountOutMin_,\n        address recipient_\n    ) external payable returns (uint256 amountOut) {\n        coinbaseWrapper.deposit{ value: msg.value }();\n        return _swapExactInput(COINBASE, tokenOut_, msg.value, amountOutMin_, recipient_);\n    }\n\n    /**\n     * @inheritdoc IMocSwapper\n     */\n    function swapCoinbaseExactOutput(\n        address tokenOut_,\n        uint256 amountOut_,\n        address recipient_\n    ) external payable returns (uint256 amountIn) {\n        coinbaseWrapper.deposit{ value: msg.value }();\n        amountIn = _swapExactOutput(COINBASE, tokenOut_, amountOut_, msg.value, recipient_);\n        // return excess coinbase\n        if (msg.value > amountIn) {\n            _unwrapAndTransfer(msg.value - amountIn, msg.sender);\n        }\n    }\n\n    /**\n     * @inheritdoc IMocSwapper\n     */\n    function swapRC20(\n        address tokenIn_,\n        address tokenOut_,\n        uint256 amountIn_,\n        uint256 amountOutMin_,\n        address recipient_\n    ) external returns (uint256 amountOut) {\n        SafeERC20.safeTransferFrom(IERC20(tokenIn_), msg.sender, address(this), amountIn_);\n        bool unwrap = tokenOut_ == COINBASE;\n        amountOut = _swapExactInput(tokenIn_, tokenOut_, amountIn_, amountOutMin_, unwrap ? address(this) : recipient_);\n\n        if (unwrap) {\n            _unwrapAndTransfer(amountOut, recipient_);\n        }\n    }\n\n    /**\n     * @inheritdoc IMocSwapper\n     */\n    function swapRC20ExactOutput(\n        address tokenIn_,\n        address tokenOut_,\n        uint256 amountOut_,\n        uint256 amountInMax_,\n        address recipient_\n    ) external returns (uint256 amountIn) {\n        SafeERC20.safeTransferFrom(IERC20(tokenIn_), msg.sender, address(this), amountInMax_);\n        bool unwrap = tokenOut_ == COINBASE;\n        amountIn = _swapExactOutput(tokenIn_, tokenOut_, amountOut_, amountInMax_, unwrap ? address(this) : recipient_);\n        // return excess tokenIn\n        if (amountInMax_ > amountIn) {\n            // reset allowance to zero\n            SafeERC20.forceApprove(IERC20(tokenIn_), address(swapRouter), 0);\n            SafeERC20.safeTransfer(IERC20(tokenIn_), msg.sender, amountInMax_ - amountIn);\n        }\n\n        if (unwrap) {\n            _unwrapAndTransfer(amountOut_, recipient_);\n        }\n    }\n\n    /**\n     * @notice Unwrap coinbase and transfer to recipient\n     * @param amount Amount to unwrap and transfer\n     * @param recipient Recipient address\n     */\n    function _unwrapAndTransfer(uint256 amount, address recipient) internal {\n        coinbaseWrapper.withdraw(amount);\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, ) = address(recipient).call{ value: amount }(\"\");\n        if (!success) revert CoinbaseTransferFailed();\n    }\n\n    /**\n     * @notice swap RC20 token method using exact input\n     * @param tokenIn_ RC20 token to send. If address(0) use the coinbase wrapper\n     * @param tokenOut_ RC20 token to receive. If address(0) use the coinbase wrapper\n     * @param amountIn_ amount of tokens to swap\n     * @param amountOutMin_ minimum amount of tokens to receive\n     * @param recipient_ address who receives the tokens\n     * @return amountOut amount of RC20 tokens received\n     */\n    function _swapExactInput(\n        address tokenIn_,\n        address tokenOut_,\n        uint256 amountIn_,\n        uint256 amountOutMin_,\n        address recipient_\n    ) internal returns (uint256 amountOut) {\n        address tokenIn = tokenIn_ == COINBASE ? address(coinbaseWrapper) : tokenIn_;\n        SafeERC20.forceApprove(IERC20(tokenIn), address(swapRouter), amountIn_);\n        IV3SwapRouter.ExactInputSingleParams memory params = IV3SwapRouter.ExactInputSingleParams({\n            tokenIn: tokenIn,\n            tokenOut: tokenOut_ == COINBASE ? address(coinbaseWrapper) : tokenOut_,\n            fee: fees[tokenIn_][tokenOut_],\n            recipient: recipient_,\n            amountIn: amountIn_,\n            amountOutMinimum: amountOutMin_,\n            sqrtPriceLimitX96: 0\n        });\n\n        uint256 balanceBefore = IERC20(tokenIn).balanceOf(address(this));\n\n        // Execute the swap\n        amountOut = swapRouter.exactInputSingle(params);\n\n        if (IERC20(tokenIn).balanceOf(address(this)) != balanceBefore - amountIn_) revert PartialSwap();\n    }\n\n    /**\n     * @notice swap RC20 token method using exact output\n     * @param tokenIn_ RC20 token to send. If address(0) use the coinbase wrapper\n     * @param tokenOut_ RC20 token to receive. If address(0) use the coinbase wrapper\n     * @param amountOut_ amount of tokens to receive in the swap\n     * @param amountInMax_ maximum amount of tokens to spend\n     * @param recipient_ address who receives the tokens\n     * @return amountIn amount of RC20 tokens spent\n     */\n    function _swapExactOutput(\n        address tokenIn_,\n        address tokenOut_,\n        uint256 amountOut_,\n        uint256 amountInMax_,\n        address recipient_\n    ) internal returns (uint256 amountIn) {\n        address tokenIn = tokenIn_ == COINBASE ? address(coinbaseWrapper) : tokenIn_;\n        address tokenOut = tokenOut_ == COINBASE ? address(coinbaseWrapper) : tokenOut_;\n        SafeERC20.forceApprove(IERC20(tokenIn), address(swapRouter), amountInMax_);\n        IV3SwapRouter.ExactOutputSingleParams memory params = IV3SwapRouter.ExactOutputSingleParams({\n            tokenIn: tokenIn,\n            tokenOut: tokenOut,\n            fee: fees[tokenIn_][tokenOut_],\n            recipient: recipient_,\n            amountOut: amountOut_,\n            amountInMaximum: amountInMax_,\n            sqrtPriceLimitX96: 0\n        });\n\n        uint256 balanceBefore = IERC20(tokenOut).balanceOf(recipient_);\n\n        // Execute the swap\n        amountIn = swapRouter.exactOutputSingle(params);\n\n        // NOTICE: When using a standard Uniswap Router, exactOutput reverts before this does.\n        // but we keep this here defensively, it's worth the gas.\n        if (IERC20(tokenOut).balanceOf(recipient_) != balanceBefore + amountOut_) revert PartialSwap();\n    }\n\n    // ------- Only Authorized Changer Functions -------\n\n    /**\n     * @notice set a pool to the swapper\n     * @param tokenA_ address of the first token. For coinbase use address(0)\n     * @param tokenB_ address of the second token. For coinbase use address(0)\n     * @param fee_ fee of the pool\n     * @param providerSwappingAtoB_ address of the max amount to swap provider for the tokenA -> tokenB pool\n     */\n    function setPool(\n        address tokenA_,\n        address tokenB_,\n        uint24 fee_,\n        IDataProvider providerSwappingAtoB_\n    ) external onlyAuthorizedChanger {\n        maxAmountToSwapProviders[tokenA_][tokenB_] = providerSwappingAtoB_;\n        fees[tokenA_][tokenB_] = fee_;\n    }\n\n    // @notice used to receive coinbase to unwrap it\n    receive() external payable {}\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/governance/Governed.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IGovernor } from \"../interfaces/IGovernor.sol\";\nimport { MocHelper } from \"../utils/MocHelper.sol\";\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n  @title Governed\n  @notice Base contract to be inherited by governed contracts\n  @dev This contract is not usable on its own since it does not have any _productive useful_ behavior\n  The only purpose of this contract is to define some useful modifiers and functions to be used on the\n  governance aspect of the child contract\n  */\nabstract contract Governed is Initializable, MocHelper {\n    /**\n    @notice The address of the contract which governs this one\n   */\n    IGovernor public governor;\n\n    error NotAuthorizedChanger();\n\n    /**\n    @notice Modifier that protects the function\n    @dev You should use this modifier in any function that should be called through\n    the governance system\n   */\n    modifier onlyAuthorizedChanger() {\n        checkIfAuthorizedChanger();\n        _;\n    }\n\n    /**\n    @notice Initialize the contract with the basic settings\n    @dev This initialize replaces the constructor but it is not called automatically.\n    It is necessary because of the upgradeability of the contracts\n    @param governorAddress_ Governor address\n   */\n    function __Governed_init(address governorAddress_) internal onlyInitializing {\n        __Governed_init_unchained(governorAddress_);\n    }\n\n    function __Governed_init_unchained(address governorAddress_) internal onlyInitializing {\n        governor = IGovernor(governorAddress_);\n    }\n\n    /**\n    @notice Change the contract's governor. Should be called through the old governance system\n    @param newGovernor_ New governor address\n   */\n    function changeGovernor(IGovernor newGovernor_) external onlyAuthorizedChanger {\n        governor = newGovernor_;\n    }\n\n    /**\n    @notice Checks if the msg sender is an authorized changer, reverts otherwise\n   */\n    function checkIfAuthorizedChanger() internal view {\n        if (!governor.isAuthorizedChanger(msg.sender)) revert NotAuthorizedChanger();\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/utils/Address.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/queue/MocQueueExecFees.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocUpgradable } from \"../governance/MocUpgradable.sol\";\nimport { MocMultiCollateralGuard } from \"../multiCollateral/MocMultiCollateralGuard.sol\";\n\n/**\n * @title MocQueue Execution Fee: Handles Queuing execution fees\n */\nabstract contract MocQueueExecFees is MocUpgradable {\n    // Set of Deferrable Operation Types\n    enum OperType {\n        none, // avoid using zero as Type\n        mintTC,\n        redeemTC,\n        mintTP,\n        redeemTP,\n        mintTCandTP,\n        redeemTCandTP,\n        swapTCforTP,\n        swapTPforTC,\n        swapTPforTP\n    }\n\n    // ------- Custom Errors -------\n\n    // Wrong amount of coinbase set as execution fee\n    error WrongExecutionFee(uint256 expectedValue);\n    // Failure on Executor payment address coinbase transfer\n    error ExecutionFeePaymentFailed();\n\n    // ------- Structs -------\n\n    struct InitializeMocQueueExecCostsParams {\n        // estimated gas units for Collateral Tokens mint execution\n        uint256 tcMintExecCost;\n        // estimated gas units for Collateral Tokens redeem execution\n        uint256 tcRedeemExecCost;\n        // estimated gas units for Pegged Tokens mint execution\n        uint256 tpMintExecCost;\n        // estimated gas units for Pegged Tokens redeem execution\n        uint256 tpRedeemExecCost;\n        // estimated gas units for swapping one Pegged Token for another Pegged Token\n        uint256 swapTPforTPExecCost;\n        // estimated gas units for swapping a Pegged Token for Collateral Token\n        uint256 swapTPforTCExecCost;\n        // estimated gas units for swapping Collateral Token for a Pegged Token\n        uint256 swapTCforTPExecCost;\n        // estimated gas units for redeeming Collateral Token and Pegged Token in one operation\n        uint256 redeemTCandTPExecCost;\n        // estimated gas units for minting Collateral Token and Pegged Token in one operation\n        uint256 mintTCandTPExecCost;\n        // estimated gas units for price updates\n        uint256 priceUpdatesCost;\n    }\n\n    // source for all buckets to determine the overall state of the multi-collateral system\n    MocMultiCollateralGuard public mocMultiCollateralGuard;\n    // OperType => estimated gas units per operation\n    mapping(OperType => uint256) public execCost;\n    // estimated gas units for price updates.\n    // If the protocol uses lazy Price Providers (oracles that update prices only when an\n    // operation is enqueued), the execution gas costs could include the full price-update cost.\n    // That extra cost is intended to compensate the corresponding oracles.\n    // It can be set to 0 if those oracles are compensated through MocFeeFlow instead.\n    uint256 public priceUpdatesCost;\n\n    // ------- Initializer -------\n\n    function __MocQueueExecFees_init(\n        InitializeMocQueueExecCostsParams calldata mocQueueExecCostsParams_\n    ) internal onlyInitializing {\n        _setExecutionCosts(mocQueueExecCostsParams_);\n    }\n\n    // ------- Abstract Functions -------\n\n    /**\n     * @notice true if the queue is empty\n     */\n    function isEmpty() public view virtual returns (bool isEmpty);\n\n    // ------- Internal Functions -------\n\n    /**\n     * @notice returns the network basefee\n     */\n    function _getBaseFee() internal view virtual returns (uint256) {\n        return block.basefee;\n    }\n\n    /**\n     * @notice sets estimated gas units for each operation type\n     */\n    function _setExecutionCosts(InitializeMocQueueExecCostsParams calldata mocQueueExecCostsParams_) internal {\n        execCost[OperType.mintTC] = mocQueueExecCostsParams_.tcMintExecCost;\n        execCost[OperType.redeemTC] = mocQueueExecCostsParams_.tcRedeemExecCost;\n        execCost[OperType.mintTP] = mocQueueExecCostsParams_.tpMintExecCost;\n        execCost[OperType.redeemTP] = mocQueueExecCostsParams_.tpRedeemExecCost;\n        execCost[OperType.swapTPforTP] = mocQueueExecCostsParams_.swapTPforTPExecCost;\n        execCost[OperType.swapTPforTC] = mocQueueExecCostsParams_.swapTPforTCExecCost;\n        execCost[OperType.swapTCforTP] = mocQueueExecCostsParams_.swapTCforTPExecCost;\n        execCost[OperType.redeemTCandTP] = mocQueueExecCostsParams_.redeemTCandTPExecCost;\n        execCost[OperType.mintTCandTP] = mocQueueExecCostsParams_.mintTCandTPExecCost;\n        priceUpdatesCost = mocQueueExecCostsParams_.priceUpdatesCost;\n    }\n\n    /**\n     * @notice gets the coinbase execution fee for the requested operation\n     * @dev only used for coinbase flavor\n     * @param operType_ operation type registered\n     * @return currentExecFee execution fee in coinbase units (gas units * basefee)\n     */\n    function getExecFee(OperType operType_) public view returns (uint256 currentExecFee) {\n        unchecked {\n            currentExecFee = (execCost[operType_] + priceUpdatesCost) * _getBaseFee();\n        }\n    }\n\n    // ------- External Functions -------\n\n    /**\n     * @notice verifies that the execution fee for the operation is in range\n     *  reverts if value sent is not enough to pay the execution fee or out of 10x range\n     * @param operType_ operation type registered\n     * @param execFee_ maximum execution fee the user is willing to accept\n     */\n    function verifyExecFeeRC20(OperType operType_, uint256 execFee_) external view {\n        uint256 currentExecFee = getExecFee(operType_);\n        if (currentExecFee > execFee_) revert WrongExecutionFee(currentExecFee);\n        // If the value sent is 10x higher than network required, we assumed user error\n        if (execFee_ > currentExecFee * 10) revert WrongExecutionFee(currentExecFee);\n    }\n\n    /**\n     * @notice verifies that the execution fee for the operation is in range\n     *  reverts if value sent is not enough to pay the execution fee\n     * @param operType_ operation type registered\n     * @param qACTotal_ maximum AC the user is willing to spend for the operation, including the execution fee\n     * @return qACmax maximum AC the user is willing to spend for the operation, excluding the execution fee\n     * @return currentExecFee execution fee for the given operation\n     */\n    function verifyExecFeeCoinbase(\n        OperType operType_,\n        uint256 qACTotal_\n    ) external view returns (uint256 qACmax, uint256 currentExecFee) {\n        currentExecFee = getExecFee(operType_);\n        if (qACTotal_ < currentExecFee) revert WrongExecutionFee(currentExecFee);\n        // for redeem operations, the coinbase overpaid is not used, so we need to revert if it is too high\n        if (operType_ == OperType.redeemTC || operType_ == OperType.redeemTP || operType_ == OperType.redeemTCandTP) {\n            // If the value sent is 10x higher than network required, we assumed user error\n            if (qACTotal_ > currentExecFee * 10) revert WrongExecutionFee(currentExecFee);\n            return (0, qACTotal_);\n        }\n        qACmax = qACTotal_ - currentExecFee;\n    }\n\n    // ------- Only Authorized Changer Functions -------\n\n    /**\n     * @notice updates estimated gas units for each operation type\n     * @dev When the changer is executed there could be pending operations on the queue, thats means that\n     *  users have already paid for those operations, so, two situations could occur:\n     *  1. If execution fees are decreased, the executor will receive all the new fees and the\n     *       remaining funds will stay in this contract\n     *  2. If execution fees are increased, the executor will receive less fees, unless this contract has funds\n     *       remaining from another execution fee update (1.) or previously sent by another address\n     * @param mocQueueExecCostsParams_ new execution fees\n     */\n    function updateExecutionCosts(\n        InitializeMocQueueExecCostsParams calldata mocQueueExecCostsParams_\n    ) external onlyAuthorizedChanger {\n        _setExecutionCosts(mocQueueExecCostsParams_);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/v3/TaskInterestPaymentV3.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../ITask.sol\";\nimport { MocOperations } from \"@moc/moc-main/contracts/core/MocOperations.sol\";\n\n/**\n * @title TaskInterestPaymentV3\n * @notice This contract implements a task that pays interest from TC holders.\n */\ncontract TaskInterestPaymentV3 is ITask {\n    MocOperations public immutable bucket;\n\n    /**\n     * @notice Constructor\n     * @param bucket_ The address of the MocOperations contract.\n     */\n    constructor(address bucket_) {\n        bucket = MocOperations(bucket_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() external view returns (bool) {\n        MocOperations bucket_ = bucket;\n        if (bucket_.paused() || bucket_.liquidated()) return false;\n        return block.timestamp >= bucket_.nextTCInterestPayment();\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        bucket.tcHoldersInterestPayment();\n    }\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/vendors/MocVendors.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocUpgradable } from \"../governance/MocUpgradable.sol\";\n\n/**\n * @title MocVendors\n * @notice MocVendors allows a third-party to add a markup to all operations\n *  A vendor can set a markup themselves or ask vendors guardian to do it on their behalf.\n *  Considerations:\n *  - Theres is not a markup limit or restriction\n *  - The currency that the vendor receives is always the same that is used to pay fees(AC or Fee Token)\n *  - A malicious vendor front running an operation increasing the markup is protected by a cooldown system\n */\ncontract MocVendors is MocUpgradable {\n    // time that must elapse for a new markup to be applied\n    uint128 public constant COOLDOWN = 1 hours;\n    // ------- Events -------\n    event VendorMarkupChanged(address indexed vendorAddress_, uint256 newMarkup_);\n    // ------- Custom Errors -------\n    error NotVendorsGuardian(address sender_);\n    error DelegateRevoked();\n    error MarkupTooHigh();\n\n    // -----------------------------\n    // ---------- Structs ----------\n    // -----------------------------\n    struct MarkupData {\n        // previous markup percentage [PREC]\n        uint64 previous; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n        // next markup percentage [PREC]\n        uint64 next; // 0% = 0; 1% = 10 ** 16; 100% = 10 ** 18\n        // markup percentage cooldown end time. After this time, new markup percentage will be applied\n        uint128 cooldownEndTime;\n    }\n\n    // ------- Storage -------\n\n    // address authorized to change a vendor's markup\n    address public vendorsGuardianAddress;\n    // DEPRECATED STORAGE SLOT\n    mapping(address => uint256) private vendorMarkupDeprecated;\n    // addition markup pct applied on each operation when operating through a vendor\n    mapping(address vendor => MarkupData markupData) public vendorMarkupData;\n    // true if the vendor has revoked the delegate for the vendors guardian to set the markup\n    mapping(address vendor => bool delegateRevoked) public delegateRevoked;\n    // max markup percentage allowed [PREC]\n    uint256 public maxMarkup;\n\n    // ------- Initializer -------\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    /**\n     * @notice contract initializer\n     * @param vendorsGuardianAddress_ The address authorized to change a vendor's markup\n     * @param governorAddress_ The address that will define when a change contract is authorized\n     * @param pauserAddress_ The address that is authorized to pause this contract\n     * @param maxMarkup_ Max markup percentage allowed [PREC]\n     */\n    function initialize(\n        address vendorsGuardianAddress_,\n        address governorAddress_,\n        address pauserAddress_,\n        uint256 maxMarkup_\n    ) external initializer {\n        // slither-disable-next-line missing-zero-check\n        vendorsGuardianAddress = vendorsGuardianAddress_;\n        maxMarkup = maxMarkup_;\n        __MocUpgradable_init(governorAddress_, pauserAddress_);\n    }\n\n    // ------- Internal Functions -------\n\n    /**\n     * @notice returns markup percentage to apply.\n     *  If there is a new one and cooldown time has expired, apply that one; otherwise, apply the previous one\n     * @param vendorAddress_ vendor address to get markup\n     * @return markup percentage to apply [PREC]\n     */\n    function _getVendorMarkup(address vendorAddress_) public view returns (uint64) {\n        MarkupData memory _markupData = vendorMarkupData[vendorAddress_];\n        if (block.timestamp >= _markupData.cooldownEndTime) {\n            return _markupData.next;\n        }\n        return _markupData.previous;\n    }\n\n    /**\n     * @notice sets a vendor markup\n     * @param vendorAddress_ vendor address to change markup\n     * @param newMarkup_ new markup applied to vendor [PREC]\n     * @param applyInstantly_ if true, the new markup will be applied instantly; \n        if false, the new markup will be applied after the cooldown\n     */\n    function _setMarkup(address vendorAddress_, uint64 newMarkup_, bool applyInstantly_) internal {\n        if (newMarkup_ > maxMarkup) revert MarkupTooHigh();\n        // reverts if the new markup is >= 100%\n        _checkLessThanOne(newMarkup_);\n        // read from storage\n        MarkupData memory _markupData = vendorMarkupData[vendorAddress_];\n\n        _markupData.previous = _getVendorMarkup(vendorAddress_);\n        _markupData.next = newMarkup_;\n        _markupData.cooldownEndTime = applyInstantly_ ? uint128(block.timestamp) : uint128(block.timestamp) + COOLDOWN;\n\n        // write to storage\n        vendorMarkupData[vendorAddress_] = _markupData;\n        emit VendorMarkupChanged(vendorAddress_, newMarkup_);\n    }\n\n    // ------- External Functions -------\n\n    /**\n     * @notice returns markup percentage to apply.\n     *  If there is a new one and cooldown time has expired, apply that one; otherwise, apply the previous one\n     * @param vendorAddress_ vendor address to get markup\n     * @return markup percentage to apply [PREC]\n     */\n    function vendorMarkup(address vendorAddress_) external view returns (uint256) {\n        return uint256(_getVendorMarkup(vendorAddress_));\n    }\n\n    /**\n     * @notice vendor sets its own markup\n     * @dev revokes the delegate for the vendors guardian to set the markup\n     * @param newMarkup_ new markup applied to vendor [PREC]\n     */\n    function setMarkup(uint64 newMarkup_) external {\n        if (!delegateRevoked[msg.sender]) delegateRevoked[msg.sender] = true;\n        _setMarkup(msg.sender, newMarkup_, false);\n    }\n\n    /**\n     * @notice governor or vendors guardian set a vendor markup.\n     * @dev governor or vendors guardian can set a vendor markup.\n     *  Changer updates are applied instantly, while vendors guardian updates use cooldown.\n     *  If the vendor has already revoked the delegate for the vendors guardian, it won't be able to set a new markup.\n     * @param vendorAddress_ vendor address to change markup\n     * @param newMarkup_ new markup applied to vendor [PREC]\n     */\n    function setVendorMarkup(address vendorAddress_, uint64 newMarkup_) external {\n        bool isVendorsGuardian = msg.sender == vendorsGuardianAddress;\n        bool isAuthorizedChanger = governor.isAuthorizedChanger(msg.sender);\n        if (!isVendorsGuardian && !isAuthorizedChanger) revert NotVendorsGuardian(msg.sender);\n        if (isVendorsGuardian && delegateRevoked[vendorAddress_]) revert DelegateRevoked();\n        // if called by vendors guardian, apply cooldown; if called by an authorized changer, apply instantly\n        _setMarkup(vendorAddress_, newMarkup_, isAuthorizedChanger);\n    }\n\n    // ------- Only Authorized Changer Functions -------\n\n    /**\n     * @dev Sets the address which will be authorized to set a vendor markup.\n     * @param vendorsGuardianAddress_ Address which will be authorized to set a vendor markup.\n     */\n    function setVendorsGuardianAddress(address vendorsGuardianAddress_) public onlyAuthorizedChanger {\n        // slither-disable-next-line missing-zero-check\n        vendorsGuardianAddress = vendorsGuardianAddress_;\n    }\n\n    /**\n     * @dev Sets the max markup percentage allowed.\n     * @param maxMarkup_ Max markup percentage allowed [PREC].\n     */\n    function setMaxMarkup(uint256 maxMarkup_) public onlyAuthorizedChanger {\n        maxMarkup = maxMarkup_;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n\n    // Purposely left unused to save some state space to allow for future upgrades\n    // slither-disable-next-line unused-state\n    uint256[50] private __gap;\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/proxy/beacon/IBeacon.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {BeaconProxy} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"},{"file_path":"project/contracts/providers/FCMaxOpDifferenceProvider.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { IDataProvider } from \"moc-main-latest/contracts/interfaces/IDataProvider.sol\";\n\n/**\n * @title Flux Capacitor Operation Difference Maximum DataProvider\n * @notice Allows the Owner, to set the value so that the protocol cold peek it.\n */\ncontract FCMaxOpDifferenceProvider is Ownable, IDataProvider {\n    bytes32 public data;\n\n    event DataUpdated(uint256 newData);\n\n    constructor(address owner_, uint256 initialData_) Ownable() {\n        _transferOwnership(owner_);\n        data = bytes32(initialData_);\n    }\n\n    function peek() external view returns (bytes32, bool) {\n        return (data, true);\n    }\n\n    function setMaxOperationalDifference(uint256 data_) external onlyOwner {\n        data = bytes32(data_);\n        emit DataUpdated(data_);\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/proxy/utils/Initializable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n     * constructor.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = !_initializing;\n        require(\n            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n            \"Initializable: contract is already initialized\"\n        );\n        _initialized = 1;\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: setting the version to 255 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint8 version) {\n        require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n        _initialized = version;\n        _initializing = true;\n        _;\n        _initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        require(!_initializing, \"Initializable: contract is initializing\");\n        if (_initialized != type(uint8).max) {\n            _initialized = type(uint8).max;\n            emit Initialized(type(uint8).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint8) {\n        return _initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _initializing;\n    }\n}\n"},{"file_path":"project/contracts/MocRif.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocCARC20 } from \"moc-main-latest/contracts/collateral/rc20/MocCARC20.sol\";\nimport { IMocRC20 } from \"moc-main-latest/contracts/interfaces/IMocRC20.sol\";\n\n/**\n * @title MocRif\n * @notice MoC Core implementation using RIF as the Collateral Asset.\n */\ncontract MocRif is MocCARC20 {\n    error AlreadyMigrated();\n\n    /**\n     * @notice Migrates the core bucket Collateral Token to a new token contract.\n     * @dev Updates the Collateral Token reference and bucket accounting balance, then mints the\n     *      corresponding amount of the new Collateral Token to the token migrator contract.\n     *      Can only be called by an authorized governance changer.\n     * @param newTCtoken_ The new Collateral Token address.\n     * @param newNTCcb_ The new Collateral Token bucket accounting balance.\n     * @param tokenMigrator_ The address that receives the newly minted Collateral Tokens for migration.\n     */\n    function migrateTCToken(\n        address newTCtoken_,\n        uint256 newNTCcb_,\n        address tokenMigrator_\n    ) external onlyAuthorizedChanger {\n        if (address(tcToken) == newTCtoken_) revert AlreadyMigrated();\n        tcToken = IMocRC20(newTCtoken_);\n        nTCcb = newNTCcb_;\n        _mintToken(tcToken, tokenMigrator_, newNTCcb_);\n    }\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/core/MocCoreExpansion.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { MocCommons, PeggedTokenParams } from \"./MocCommons.sol\";\nimport { IMocRC20 } from \"../interfaces/IMocRC20.sol\";\nimport { IMocMultiCollateralGuard } from \"../interfaces/IMocMultiCollateralGuard.sol\";\nimport { IPriceProvider } from \"../interfaces/IPriceProvider.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\n/**\n * @title MocCoreExpansion\n * @notice This contract is used as an expansion of MocCore because 24kb size limitation\n *  MocCore delegate some function calls to it.\n * @dev IMPORTANT NOTES:\n *  1. MocCore and MocCoreExpansion must have always the same storage layout to avoid collisions\n *  2. Because MocCore is upgradeable and delegates calls to MocCoreExpansion, it cannot be upgradeable because\n *      a proxy contract cannot delegate calls to another proxy contract. So, for any MocCoreExpansion upgrade\n *      you must deploy a new implementation and set it to MocCore.\n */\ncontract MocCoreExpansion is MocCommons {\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    /**\n     * @notice add a Pegged Token to the protocol\n     * @dev Note that the ema value, should consider `nextEmaCalculation`\n     *  This function is called by MocCore contract using it's context with delegate call\n     *  Checks done there:\n     *  -  onlyAuthorizedChanger: the caller must have governance authorization.\n     * @param tpToken_ Pegged Token contract to add\n     *  peggedTokenParams_ params of Pegged Token to add:\n     *      priceProviderAddress Pegged Token price provider contract address\n     *      tpCtarg Pegged Token target coverage [PREC]\n     *      tpMintFee additional fee pct applied on mint [PREC]\n     *      tpRedeemFee additional fee pct applied on redeem [PREC]\n     *      tpEma initial Pegged Token exponential moving average [PREC]\n     *      tpEmaSf Pegged Token smoothing factor [PREC]\n     * @dev Pegged Token should be added using the corresponding changer template, which\n     *      should guarantee that it is added on all the buckets(mandatory for multiCollateral)\n     *\n     *  Requirements:\n     *\n     *  - tpTokenAddress must be a MocRC20, with mint, burn roles already settled\n     *  for this contract\n     */\n    function addPeggedToken(IMocRC20 tpToken_, PeggedTokenParams calldata peggedTokenParams_) external {\n        IPriceProvider priceProvider = IPriceProvider(peggedTokenParams_.priceProviderAddress);\n\n        if (peggedTokenIndex[address(tpToken_)].exists) revert PeggedTokenAlreadyAdded();\n        uint256 newTPindex = uint256(tpTokens.length);\n        peggedTokenIndex[address(tpToken_)] = PeggedTokenIndex({ index: newTPindex, exists: true });\n\n        // set Pegged Token address\n        tpTokens.push(tpToken_);\n        // set peg container item\n        pegContainer.push(PegContainerItem({ nTP: 0, priceProvider: priceProvider }));\n        // set target coverage\n        tpCtarg.push(peggedTokenParams_.tpCtarg);\n        // set mint fee pct\n        tpMintFees[address(tpToken_)] = peggedTokenParams_.tpMintFee;\n        // set redeem fee pct\n        tpRedeemFees[address(tpToken_)] = peggedTokenParams_.tpRedeemFee;\n        // set EMA initial value and smoothing factor\n        tpEma.push(EmaItem({ ema: peggedTokenParams_.tpEma, sf: peggedTokenParams_.tpEmaSf }));\n        tpiou.push();\n\n        /**\n         * Price providers may not be valid at the time of adding a\n         * pegged token, so we initialize the last token price with a fixed value.\n         * This value should be realistic, otherwise it would momentarily affect the\n         * successFee calculation when the protocol starts operating.\n         */\n        pACtpLstop.push(peggedTokenParams_.tpEma);\n        // emit the event\n        emit PeggedTokenChange(newTPindex, address(tpToken_), peggedTokenParams_);\n    }\n\n    /**\n     * @notice modifies a Pegged Token of the protocol\n     * @dev Note that the ema value, should consider `nextEmaCalculation`\n     *  This function is called by MocCore contract using it's context with delegate call\n     *  Checks done there:\n     *  -  onlyAuthorizedChanger: the caller must have governance authorization.\n     * @param tpToken_ Pegged Token contract to edit\n     *  peggedTokenParams_ params of Pegged Token to edit:\n     *      priceProviderAddress Pegged Token price provider contract address\n     *      tpCtarg Pegged Token target coverage [PREC]\n     *      tpMintFee additional fee pct applied on mint [PREC]\n     *      tpRedeemFee additional fee pct applied on redeem [PREC]\n     *      tpEma initial Pegged Token exponential moving average [PREC]\n     *      tpEmaSf Pegged Token smoothing factor [PREC]\n     *\n     *  Requirements:\n     *\n     * - the tpTokenAddress must exists\n     */\n    function editPeggedToken(IMocRC20 tpToken_, PeggedTokenParams calldata peggedTokenParams_) external {\n        PeggedTokenIndex memory ptIndex = peggedTokenIndex[address(tpToken_)];\n        if (!ptIndex.exists) revert InvalidAddress();\n        uint256 i = ptIndex.index;\n        pegContainer[i].priceProvider = IPriceProvider(peggedTokenParams_.priceProviderAddress);\n        // set target coverage\n        tpCtarg[i] = peggedTokenParams_.tpCtarg;\n        // set mint fee pct\n        tpMintFees[address(tpToken_)] = peggedTokenParams_.tpMintFee;\n        // set redeem fee pct\n        tpRedeemFees[address(tpToken_)] = peggedTokenParams_.tpRedeemFee;\n        // set EMA initial value and smoothing factor\n        tpEma[i].sf = peggedTokenParams_.tpEmaSf;\n        // emit the event\n        emit PeggedTokenChange(i, address(tpToken_), peggedTokenParams_);\n    }\n\n    /**\n     * @dev Calculates price at liquidation event as a relation between Pegs total supply\n     * and the amount of Asset Collateral available to distribute\n     */\n    function settleLiquidationPrices() external {\n        // Total amount of AC available to be redeemed\n        uint256 totalACAvailable = nACcb;\n        // slither-disable-next-line incorrect-equality\n        if (totalACAvailable == 0) return;\n        uint256 pegAmount = pegContainer.length;\n        // this could be get by getLckAC(), but given the prices are needed after,\n        // it's better to cache them here.\n        uint256 lckAC;\n        // Auxiliary cache of pegs pACtp\n        uint256[] memory pACtps = new uint256[](pegAmount);\n        // for each peg, calculates the proportion of AC reserves it's locked\n\n        for (uint256 i = 0; i < pegAmount; i = unchecked_inc(i)) {\n            pACtps[i] = _getPACtp(i);\n            // [N] = [N] * [PREC] / [PREC]\n            lckAC += _divPrec(pegContainer[i].nTP, pACtps[i]);\n        }\n        for (uint256 i = 0; i < pegAmount; i = unchecked_inc(i)) {\n            // [PREC] = [PREC] * [N] / [N];\n            tpLiqPrices.push((pACtps[i] * lckAC) / totalACAvailable);\n        }\n    }\n\n    /**\n     * @notice Allow redeem on liquidation state, user Peg balance gets burned\n     * @dev This function is called by MocCore contract using it's context with delegate call\n     *  The equivalent AC given the liquidation frozen price(qACRedeemed) is transferred\n     *  to the `recipient_` by MocCore contract\n     *  Checks done there:\n     *  -  notPaused: the contract must be unpaused\n     * @param tp_ Pegged Token address\n     * @param sender_ address owner of the TP to be redeemed\n     * @param recipient_ address who receives the AC\n     * @return qACRedeemed amount of AC sent to `recipient_`\n     */\n    function liqRedeemTP(\n        address tp_,\n        address sender_,\n        address recipient_,\n        uint256 mocACBalance\n    ) external returns (uint256 qACRedeemed) {\n        if (!liquidated) revert OnlyWhenLiquidated();\n        uint256 i = _tpi(tp_);\n        uint256 qTP = tpTokens[i].balanceOf(sender_);\n        // slither-disable-next-line incorrect-equality\n        if (qTP == 0) revert InsufficientTPtoRedeem(qTP, qTP);\n        // [PREC]\n        uint256 liqPACtp = tpLiqPrices[i];\n        // [PREC] = [N] * [PREC] / [PREC]\n        qACRedeemed = _divPrec(qTP, liqPACtp);\n        // Given rounding errors, the last redeemer might receive a little less\n        if (mocACBalance < qACRedeemed) qACRedeemed = mocACBalance;\n        // in liquidation doesn't pay fees or markup\n        // qACfee, qFeeToken, qACVendorMarkup, qFeeTokenVendorMarkup  = (0, 0, 0, 0)\n        emit LiqTPRedeemed(tp_, sender_, recipient_, qTP, qACRedeemed);\n        // burn qTP from the sender\n        tpTokens[i].burn(sender_, qTP);\n    }\n\n    /**\n     * @notice mint Collateral Token and Pegged Token in exchange for Collateral Asset\n     *  This operation is done without checking coverage\n     *  Collateral Token and Pegged Token are minted in equivalent proportions so that its price\n     *  and global coverage are not modified.\n     *  Reverts if qAC sent are insufficient.\n     * @param params_ mint TC and TP function parameters\n     * @dev\n     *      i_ Pegged Token index\n     *      qTP_ amount of Pegged Token to mint\n     *      qACmax_ maximum amount of Collateral Asset that can be spent\n     *      sender_ address who sends Collateral Asset\n     *      recipient_ address who receives the Collateral Token and Pegged Token\n     *      vendor_ address who receives a markup. If its address(0) no markup is applied\n     * @return qACtoMintTC amount of AC used to mint Collateral Token\n     * @return qACtoMintTP amount of AC used to mint Pegged Token\n     * @return qACtoSpent total amount of AC spent by `sender_` for TC and TP mint plus fees\n     * @return qTCtoMint amount of Collateral Token minted\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function mintTCandTPto(\n        MintTCandTPParams memory params_\n    )\n        external\n        payable\n        returns (\n            uint256 qACtoMintTC,\n            uint256 qACtoMintTP,\n            uint256 qACtoSpent,\n            uint256 qTCtoMint,\n            FeeCalcs memory feeCalcs\n        )\n    {\n        uint256[] memory pACtps = _getPACtps();\n        uint256 localProtThrld = protThrld;\n        uint256 i = _tpi(params_.tp);\n        uint256 pACtp = pACtps[i];\n        _updateTPtracking(i, pACtp);\n        // evaluates whether or not the system coverage is healthy, reverts if it's not\n        (uint256 lckAC, uint256 nACgain) = _evalCoverage(localProtThrld, pACtps);\n        (qTCtoMint, qACtoMintTC, qACtoMintTP) = _calcQACforMintTCandTP(\n            params_.qTP,\n            pACtp,\n            _getCtargemaTP(i, pACtp, localProtThrld),\n            _getPTCac(lckAC, nACgain)\n        );\n        uint256 qACNeededtoMint = qACtoMintTC + qACtoMintTP;\n        uint256 qACSurcharges;\n        (qACSurcharges, feeCalcs) = _calcFees(params_.sender, params_.vendor, qACNeededtoMint, mintTCandTPFee);\n        qACtoSpent = qACNeededtoMint + qACSurcharges;\n        if (qACtoSpent > params_.qACmax) revert InsufficientQacSent(params_.qACmax, qACtoSpent);\n        // if is 0 reverts because it is trying to mint an amount below precision\n        // slither-disable-next-line incorrect-equality\n        if (qACtoSpent == 0) revert QacNeededMustBeGreaterThanZero();\n        // update flux capacitor and reverts if not allowed by accumulators\n        _updateAccumulatorsOnMintTP(qACtoMintTP);\n        _depositAndMintTC(qTCtoMint, qACNeededtoMint, params_.recipient);\n        _depositAndMintTP(i, params_.qTP, 0, params_.recipient);\n    }\n\n    /**\n     * @notice redeem Collateral Asset in exchange for Collateral Token and Pegged Token\n     *  This operation is done without checking coverage\n     *  Collateral Token and Pegged Token are redeemed in equivalent proportions so that its price\n     *  and global coverage are not modified.\n     *  Reverts if qTC sent are insufficient.\n     * @param params_ redeem TC and TP function parameters\n     * @dev\n     *      i_ Pegged Token index\n     *      qTC_ maximum amount of Collateral Token to redeem\n     *      qTP_ amount of Pegged Token to redeem\n     *      qACmin_ minimum amount of Collateral Asset that `recipient_` expects to receive\n     *      sender_ address who sends Collateral Token and Pegged Token\n     *      recipient_ address who receives the Collateral Asset\n     *      vendor_ address who receives a markup. If its address(0) no markup is applied\n     * @return qACtoRedeemTC amount of AC sent to `recipient_` for Collateral Token redemption\n     * @return qACtoRedeemTP amount of AC sent to `recipient_` for Pegged Token redemption\n     * @return qACtoReceive total amount of AC sent to `recipient_` for TC and TP redemption minus fees\n     * @return qTCtoRedeem amount of Collateral Token redeemed\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function redeemTCandTPto(\n        RedeemTCandTPParams memory params_\n    )\n        external\n        payable\n        returns (\n            uint256 qACtoRedeemTC,\n            uint256 qACtoRedeemTP,\n            uint256 qACtoReceive,\n            uint256 qTCtoRedeem,\n            FeeCalcs memory feeCalcs\n        )\n    {\n        IMocMultiCollateralGuard mocMultiCollateralGuard = _getMocMultiCollateralGuard();\n        // emas are updated here\n        (uint256 combinedCglb, uint256 combinedCtargemaCA, uint256[] memory pACtps) = mocMultiCollateralGuard\n            .getCombinedValues(address(this));\n\n        uint256 i = _tpi(params_.tp);\n        uint256 pACtp = pACtps[i];\n        _updateTPtracking(i, pACtp);\n\n        uint256 ctargemaCA = _calcCtargemaCA(pACtps);\n        (uint256 lckAC, uint256 nACgain) = _getLckACandACgain(pACtps);\n        uint256 cglb = _getCglb(lckAC, nACgain);\n\n        if (cglb <= ONE) {\n            if (mocMultiCollateralGuard.getBucketAmount() > 1) revert OnlyWhenLastBucket();\n            // [PREC] = [PREC] * [N] / [N]\n            uint256 acAvailable = _getTotalACavailable(nACgain);\n            uint256 tpPrice = (pACtp * lckAC) / acAvailable;\n            qACtoRedeemTP = _divPrec(params_.qTP, tpPrice);\n            // limit qACtoRedeem to do not revert because of rounding errors\n            qACtoRedeemTP = Math.min(qACtoRedeemTP, acAvailable);\n            // [N] = [N] * [N] / [N]\n            qTCtoRedeem = (nTCcb * qACtoRedeemTP) / acAvailable;\n            qACtoRedeemTC = 0;\n        } else {\n            if (combinedCglb <= ONE) revert LowCombinedCoverage();\n            uint256 ctargemaTPMinusONE = _getCtargemaTP(i, pACtp, protThrld) - ONE;\n            uint256 score = ((cglb - ONE) * ctargemaTPMinusONE) / (ctargemaCA - ONE);\n            uint256 combinedScore = ((combinedCglb - ONE) * ctargemaTPMinusONE) / (combinedCtargemaCA - ONE);\n            // [PREC] = [PREC] * [PREC] / [PREC]\n            uint256 redeemProportion = Math.min(score, combinedScore);\n            // calculate how many qAC are redeemed for TP\n            // [N] = [N] * [PREC] / [PREC]\n            qACtoRedeemTP = _divPrec(params_.qTP, pACtp);\n            // calculate how many qAC are redeemed for TC\n            // [N] = [N] * [PREC] / [PREC]\n            qACtoRedeemTC = (params_.qTP * redeemProportion) / pACtp;\n            // [N] = [N] * [N] * [PREC] / [N] * [PREC]\n            qTCtoRedeem = (params_.qTP * redeemProportion * nTCcb) / ((_getTotalACavailable(nACgain) - lckAC) * pACtp);\n        }\n\n        // if is 0 reverts because it is trying to redeem an amount of TP or TC below precision\n        // slither-disable-next-line incorrect-equality\n        if (qACtoRedeemTP == 0 || qTCtoRedeem == 0) revert QacNeededMustBeGreaterThanZero();\n        if (qTCtoRedeem > params_.qTC) revert InsufficientQtcSent(params_.qTC, qTCtoRedeem);\n        uint256 qACtotalToRedeem = qACtoRedeemTC + qACtoRedeemTP;\n        uint256 qACSurcharges;\n        (qACSurcharges, feeCalcs) = _calcFees(params_.sender, params_.vendor, qACtotalToRedeem, redeemTCandTPFee);\n        qACtoReceive = qACtotalToRedeem - qACSurcharges;\n        if (qACtoReceive < params_.qACmin) revert QacBelowMinimumRequired(params_.qACmin, qACtoReceive);\n        // update flux capacitor and reverts if not allowed by accumulators\n        _updateAccumulatorsOnRedeemTP(qACtoRedeemTP);\n        _withdrawAndBurnTC(qTCtoRedeem, qACtotalToRedeem);\n        _withdrawAndBurnTP(i, params_.qTP, 0);\n    }\n\n    /**\n     * @notice swap Pegged Token to another one\n     *  This operation is done without checking coverage unless the target coverage for\n     *  received Pegged Token is greater than the Pegged Token sent\n     * @dev This function is called by MocCore contract using it's context with delegate call\n     * @param params_ swap TP for TP function parameters\n     * @dev\n     *      iFrom_ owned Pegged Token index\n     *      iTo_ target Pegged Token index\n     *      qTP_ amount of owned Pegged Token to swap\n     *      qTPmin_ minimum amount of target Pegged Token that `recipient_` expects to receive\n     *      qACmax_ maximum amount of Collateral Asset that can be spent in fees\n     *      sender_ address who sends the Pegged Token\n     *      recipient_ address who receives the target Pegged Token\n     *      vendor_ address who receives a markup. If its address(0) no markup is applied\n     * @return qACSurcharges amount of AC used to pay fees and markup\n     * @return qTPtoMint amount of Pegged Token minted\n     * @return feeCalcs struct with:\n     * @dev\n     *      qACFee amount of AC needed to pay fees\n     *      qFeeToken amount of Fee Token needed to pay fess\n     *      qACVendorMarkup amount of AC needed to pay vendor markup\n     *      qFeeTokenVendorMarkup amount of Fee Token needed to pay vendor markup\n     */\n    function swapTPforTPto(\n        SwapTPforTPParams memory params_\n    ) external payable returns (uint256 qACSurcharges, uint256 qTPtoMint, FeeCalcs memory feeCalcs) {\n        if (params_.tpFrom == params_.tpTo) revert InvalidValue();\n        uint256[] memory pACtps = _getPACtps();\n        uint256 iFrom = _tpi(params_.tpFrom);\n        uint256 iTo = _tpi(params_.tpTo);\n        uint256 pACtpFrom = pACtps[iFrom];\n        uint256 pACtpTo = pACtps[iTo];\n        uint256 localProtThrld = protThrld;\n        _updateTPtracking(iFrom, pACtpFrom);\n        _updateTPtracking(iTo, pACtpTo);\n        // calculate how many total qAC are redeemed\n        // [N] = [N] * [PREC] / [PREC]\n        uint256 qACtotalToRedeem = _divPrec(params_.qTP, pACtpFrom);\n        // calculate how many qTP can mint with the given qAC\n        // [N] = [N] * [PREC] / [PREC]\n        qTPtoMint = (params_.qTP * pACtpTo) / pACtpFrom;\n        if (qTPtoMint < params_.qTPmin || qTPtoMint == 0) revert QtpBelowMinimumRequired(params_.qTPmin, qTPtoMint);\n\n        bool ctargemaTPRelation = _getCtargemaTP(iTo, pACtpTo, localProtThrld) >\n            _getCtargemaTP(iFrom, pACtpFrom, localProtThrld);\n        // if ctargemaTPto > ctargemaTPfrom we need to check coverage\n        if (ctargemaTPRelation) {\n            // emas are updated here and multi collateral status evaluated, reverts if it is not healthy enough\n            (uint256 tpAvailableToMint, ) = _getMocMultiCollateralGuard().getCombinedAndTP(address(this), params_.tpTo);\n\n            uint256 ctargemaCA = _calcCtargemaCA(pACtps);\n            // evaluates whether or not the system coverage is healthy enough to mint TP\n            // given the target coverage adjusted by the moving average, reverts if it's not\n            _evalCoverage(ctargemaCA, pACtps);\n            // evaluates if there are enough TP available to mint, reverts if it's not\n            _evalTPavailableToMint(qTPtoMint, tpAvailableToMint);\n        }\n        (qACSurcharges, feeCalcs) = _calcFees(params_.sender, params_.vendor, qACtotalToRedeem, swapTPforTPFee);\n        if (qACSurcharges > params_.qACmax) revert InsufficientQacSent(params_.qACmax, feeCalcs.qACFee);\n        _depositAndMintTP(iTo, qTPtoMint, 0, params_.recipient);\n        _withdrawAndBurnTP(iFrom, params_.qTP, 0);\n    }\n\n    /**\n     * @notice swap Pegged Token to Collateral Token\n     * @dev This function is called by MocCore contract using it's context with delegate call\n     * @param params_ swap TP for TC function parameters\n     * @dev\n     *      i_ Pegged Token index\n     *      qTP_ amount Pegged Token to swap\n     *      qTCmin_ minimum amount of Collateral Token that `recipient_` expects to receive\n     *      qACmax_ maximum amount of Collateral Asset that can be spent in fees\n     *      sender_ address who sends the Pegged Token\n     *      recipient_ address who receives Collateral Token\n     *      vendor_ address who receives a markup. If its address(0) no markup is applied\n     * @return qACSurcharges amount of AC used to pay fees and markup\n     * @return qTCtoMint amount of Collateral Token minted\n     * @return feeCalcs struct with:\n     * @dev\n     *      qACFee amount of AC needed to pay fees\n     *      qFeeToken amount of Fee Token needed to pay fess\n     *      qACVendorMarkup amount of AC needed to pay vendor markup\n     *      qFeeTokenVendorMarkup amount of Fee Token needed to pay vendor markup\n     */\n    function swapTPforTCto(\n        SwapTPforTCParams memory params_\n    ) external payable returns (uint256 qACSurcharges, uint256 qTCtoMint, FeeCalcs memory feeCalcs) {\n        uint256[] memory pACtps = _getPACtps();\n        uint256 i = _tpi(params_.tp);\n        uint256 pACtp = pACtps[i];\n        _updateTPtracking(i, pACtp);\n        // evaluates whether or not the system coverage is healthy enough to mint TC, reverts if it's not\n        (uint256 lckAC, uint256 nACgain) = _evalCoverage(protThrld, pACtps);\n        // calculate how many total qAC are redeemed TP\n        // [N] = [N] * [PREC] / [PREC]\n        uint256 qACtotalToRedeem = _divPrec(params_.qTP, pACtp);\n        // calculate how many qTC can mint with the given qAC\n        // qTCtoMint = qTP / pTCac / pACtp\n        // [N] = [N] * [N] * [PREC] / ([N] - [N]) * [PREC]\n        qTCtoMint = _divPrec(params_.qTP * nTCcb, (_getTotalACavailable(nACgain) - lckAC) * pACtp);\n        // slither-disable-next-line incorrect-equality\n        if (qTCtoMint < params_.qTCmin || qTCtoMint == 0) revert QtcBelowMinimumRequired(params_.qTCmin, qTCtoMint);\n\n        (qACSurcharges, feeCalcs) = _calcFees(params_.sender, params_.vendor, qACtotalToRedeem, swapTPforTCFee);\n        if (qACSurcharges > params_.qACmax) revert InsufficientQacSent(params_.qACmax, feeCalcs.qACFee);\n        // update flux capacitor and reverts if not allowed by accumulators\n        _updateAccumulatorsOnRedeemTP(qACtotalToRedeem);\n        _withdrawAndBurnTP(i, params_.qTP, 0);\n        _depositAndMintTC(qTCtoMint, 0, params_.recipient);\n    }\n\n    /**\n     * @notice swap Collateral Token to Pegged Token\n     * @dev This function is called by MocCore contract using it's context with delegate call\n     * @param params_ swap TC for TP function parameters\n     * @dev\n     *      i_ Pegged Token index\n     *      qTC_ amount of Collateral Token to swap\n     *      qTPmin_ minimum amount of Pegged Token Token that `recipient_` expects to receive\n     *      qACmax_ maximum amount of Collateral Asset that can be spent in fees\n     *      sender_ address who sends the Collateral Token\n     *      recipient_ address who receives the Pegged Token\n     *      vendor_ address who receives a markup. If its address(0) no markup is applied\n     * @return qACSurcharges amount of AC used to pay fees and markup\n     * @return qTPtoMint amount of Pegged Token minted\n     * @dev\n     *      qACFee amount of AC needed to pay fees\n     *      qFeeToken amount of Fee Token needed to pay fess\n     *      qACVendorMarkup amount of AC needed to pay vendor markup\n     *      qFeeTokenVendorMarkup amount of Fee Token needed to pay vendor markup\n     */\n    function swapTCforTPto(\n        SwapTCforTPParams memory params_\n    ) external payable returns (uint256 qACSurcharges, uint256 qTPtoMint, FeeCalcs memory feeCalcs) {\n        // emas are updated here and multi collateral status evaluated, reverts if it is not healthy enough\n        (\n            uint256 tcAvailableToRedeem,\n            uint256 tpAvailableToMint,\n            uint256[] memory pACtps\n        ) = _getMocMultiCollateralGuard().getCombinedAndTCAndTP(address(this), params_.tp);\n\n        uint256 ctargemaCA = _calcCtargemaCA(pACtps);\n        uint256 i = _tpi(params_.tp);\n        uint256 pACtp = pACtps[i];\n        _updateTPtracking(i, pACtp);\n        // evaluates whether or not the system coverage is healthy enough to redeem TC and mint TP\n        // given the target coverage adjusted by the moving average, reverts if it's not\n        (uint256 lckAC, uint256 nACgain) = _evalCoverage(ctargemaCA, pACtps);\n        // evaluates if there are enough Collateral Tokens available to redeem, reverts if there are not\n        _evalTCAvailableToRedeem(params_.qTC, tcAvailableToRedeem);\n        // calculate how many total qAC are redeemed\n        // [N] = [N] * [PREC] / [PREC]\n        uint256 qACtotalToRedeem = _mulPrec(params_.qTC, _getPTCac(lckAC, nACgain));\n        // if is 0 reverts because it is trying to swap an amount below precision\n        // slither-disable-next-line incorrect-equality\n        if (qACtotalToRedeem == 0) revert QacNeededMustBeGreaterThanZero();\n        // calculate how many qTP can mint with the given qAC\n        // qTPtoMint = qTC * pTCac * pACtp\n        // [N] = ([N] * ([N] - [N]) * [PREC] / [N]) / [PREC]\n        qTPtoMint = ((params_.qTC * (_getTotalACavailable(nACgain) - lckAC) * pACtp) / nTCcb) / PRECISION;\n        // evaluates if there are enough TP available to mint, reverts if it's not\n        _evalTPavailableToMint(qTPtoMint, tpAvailableToMint);\n        if (qTPtoMint < params_.qTPmin) revert QtpBelowMinimumRequired(params_.qTPmin, qTPtoMint);\n\n        (qACSurcharges, feeCalcs) = _calcFees(params_.sender, params_.vendor, qACtotalToRedeem, swapTCforTPFee);\n        if (qACSurcharges > params_.qACmax) revert InsufficientQacSent(params_.qACmax, feeCalcs.qACFee);\n        // update flux capacitor and reverts if not allowed by accumulators\n        _updateAccumulatorsOnMintTP(qACtotalToRedeem);\n        _withdrawAndBurnTC(params_.qTC, 0);\n        _depositAndMintTP(i, qTPtoMint, 0, params_.recipient);\n    }\n\n    /**\n     * @notice calculate how many Collateral Asset are needed to mint an amount of Collateral Token\n     * and Pegged Token in one operation\n     * @param qTP_ amount of Pegged Token to mint\n     * @param pACtp_ Pegged Token price [PREC]\n     * @param ctargemaTP_ target coverage adjusted by the moving average of the value of a Pegged Token\n     * @param pTCac_ Collateral Token price [PREC]\n     * @return qTCtoMint amount of Collateral Token to mint [N]\n     * @return qACtoMintTC amount of Collateral Asset needed to mint Collateral Token [N]\n     * @return qACtoMintTP amount of Collateral Asset used to mint Pegged Token [N]\n     */\n    function _calcQACforMintTCandTP(\n        uint256 qTP_,\n        uint256 pACtp_,\n        uint256 ctargemaTP_,\n        uint256 pTCac_\n    ) internal pure returns (uint256 qTCtoMint, uint256 qACtoMintTC, uint256 qACtoMintTP) {\n        // calculate how many TC are needed to mint TP and total qAC used for mint both\n        // [N] = [N] * ([PREC] - [PREC]) / [PREC]\n        qACtoMintTC = (qTP_ * (ctargemaTP_ - ONE)) / pACtp_;\n        // [N] = [N] *  [PREC] / [PREC]\n        qTCtoMint = _divPrec(qACtoMintTC, pTCac_);\n        // [N] = [N] *  [PREC] / [PREC]\n        qACtoMintTP = _divPrec(qTP_, pACtp_);\n        return (qTCtoMint, qACtoMintTC, qACtoMintTP);\n    }\n\n    /**\n     * @notice calculate how many Collateral Asset are needed to redeem an amount of Collateral Token\n     * and Pegged Token in one operation\n     * @param qTC_ amount of Collateral Token to redeem\n     * @param qTP_ amount of Pegged Token to redeem\n     * @param pACtp_ Pegged Token price [PREC]\n     * @param pTCac_ Collateral Token price [PREC]\n     * @return qACtoRedeemTC amount of Collateral Asset needed to redeem Collateral Token [N]\n     * @return qACtoRedeemTP amount of Collateral Asset used to redeem Pegged Token [N]\n     */\n    function _calcQACforRedeemTCandTP(\n        uint256 qTC_,\n        uint256 qTP_,\n        uint256 pACtp_,\n        uint256 pTCac_\n    ) internal pure returns (uint256 qACtoRedeemTC, uint256 qACtoRedeemTP) {\n        // calculate how many total qAC are redeemed\n        // [N] = [N] * [PREC] / [PREC]\n        qACtoRedeemTP = _divPrec(qTP_, pACtp_);\n        // if is 0 reverts because it is trying to redeem an amount of TP below precision\n        // we check it here to prevent qTP == 0 && qTC != 0\n        // slither-disable-next-line incorrect-equality\n        if (qACtoRedeemTP == 0) revert QacNeededMustBeGreaterThanZero();\n        // calculate how many qAC are redeemed because TC\n        // [N] = [N] * [PREC] / [PREC]\n        qACtoRedeemTC = _mulPrec(qTC_, pTCac_);\n        return (qACtoRedeemTC, qACtoRedeemTP);\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/utils/math/SignedMath.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\n        }\n    }\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/interfaces/IERC1967.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n *\n * _Available since v4.8.3._\n */\ninterface IERC1967 {\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Emitted when the beacon is changed.\n     */\n    event BeaconUpgraded(address indexed beacon);\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/interfaces/IERC1967Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n *\n * _Available since v4.8.3._\n */\ninterface IERC1967Upgradeable {\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Emitted when the beacon is changed.\n     */\n    event BeaconUpgraded(address indexed beacon);\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/proxy/ERC1967/ERC1967Upgrade.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/IERC1967.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n */\nabstract contract ERC1967Upgrade is IERC1967 {\n    // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n    bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Perform implementation upgrade\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeTo(address newImplementation) internal {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n    }\n\n    /**\n     * @dev Perform implementation upgrade with additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\n        _upgradeTo(newImplementation);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(newImplementation, data);\n        }\n    }\n\n    /**\n     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\n        // Upgrades from old implementations will perform a rollback test. This test requires the new\n        // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n        // this special case will break upgrade paths from old UUPS implementation to new ones.\n        if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n            _setImplementation(newImplementation);\n        } else {\n            try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n                require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n            } catch {\n                revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n            }\n            _upgradeToAndCall(newImplementation, data, forceCall);\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _getAdmin() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n        StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     */\n    function _changeAdmin(address newAdmin) internal {\n        emit AdminChanged(_getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n     */\n    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function _getBeacon() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the EIP1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n        require(\n            Address.isContract(IBeacon(newBeacon).implementation()),\n            \"ERC1967: beacon implementation is not a contract\"\n        );\n        StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n    }\n\n    /**\n     * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n     *\n     * Emits a {BeaconUpgraded} event.\n     */\n    function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\n        _setBeacon(newBeacon);\n        emit BeaconUpgraded(newBeacon);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n        }\n    }\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/interfaces/IGovernor.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IChangeContract } from \"./IChangeContract.sol\";\n\n/**\n  @title IGovernor\n  @notice Governor interface. This functions should be overwritten to\n  enable the communication with the rest of the system\n  @dev This interface **MUST** be compatible with the corresponding Governance instance\n  used on Production, from https://github.com/money-on-chain/Areopagus-Governance\n  */\ninterface IGovernor {\n    /**\n    @notice Function to be called to make the changes described in changeContract\n    @dev This function should be protected somehow to only execute changes that\n    benefit the system. This decision process is independent of this architecture\n    therefore is independent of this interface too\n    @param changeContract_ Address of the contract that will execute the changes\n   */\n    function executeChange(IChangeContract changeContract_) external;\n\n    /**\n    @notice Returns whether this `changer_` is authorized to execute changes.\n    @param changer_ Address of the contract that will execute the changes\n   */\n    function isAuthorizedChanger(address changer_) external view returns (bool);\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/utils/structs/EnumerableSetUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Set type with\n    // bytes32 values.\n    // The Set implementation uses private functions, and user-facing\n    // implementations (such as AddressSet) are just wrappers around the\n    // underlying Set.\n    // This means that we can only create new EnumerableSets for types that fit\n    // in bytes32.\n\n    struct Set {\n        // Storage of set values\n        bytes32[] _values;\n        // Position of the value in the `values` array, plus 1 because index 0\n        // means a value is not in the set.\n        mapping(bytes32 => uint256) _indexes;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, bytes32 value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._indexes[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\n        // We read and store the value's index to prevent multiple reads from the same storage slot\n        uint256 valueIndex = set._indexes[value];\n\n        if (valueIndex != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 toDeleteIndex = valueIndex - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (lastIndex != toDeleteIndex) {\n                bytes32 lastValue = set._values[lastIndex];\n\n                // Move the last value to the index where the value to delete is\n                set._values[toDeleteIndex] = lastValue;\n                // Update the index for the moved value\n                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the index for the deleted slot\n            delete set._indexes[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\n        return set._indexes[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set) private view returns (bytes32[] memory) {\n        return set._values;\n    }\n\n    // Bytes32Set\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        bytes32[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressSet\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(AddressSet storage set, address value) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(AddressSet storage set, address value) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        address[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintSet\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        uint256[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n}\n"},{"file_path":"npm/price-oracle-interfaces@0.1.0/contracts/interfaces/ICoinPairPrice.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\n/**\n * @notice Get price of a Token. See https://github.com/money-on-chain/OMoC-Decentralized-Oracle\n * @dev Interface of OMoC-Decentralized-Oracle, compatible with MOC.\n */\ninterface ICoinPairPrice {\n  /**\n   * @notice returns the given `price` for the asset if `valid`\n   * @return price assetPrice\n   * @return valid true if the price is valid\n   */\n  function peek() external view returns (bytes32 price, bool valid);\n\n  /**\n   * @notice returns the last publication block of an asset price\n   * @dev only valid for decentralized oracles\n   * @return lastPublicationBlock\n   */\n  function getLastPublicationBlock() external view returns (uint256 lastPublicationBlock);\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/v1/TaskInterestPaymentV1.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../ITask.sol\";\n\n/**\n * @title TaskInterestPaymentV1\n * @notice This contract implements a task that pays interest from BitPro holders.\n */\ncontract TaskInterestPaymentV1 is ITask {\n    IMocV1 public immutable mocV1;\n\n    /**\n     * @notice Constructor\n     * @param mocV1_ The address of the Moc contract.\n     */\n    constructor(address mocV1_) {\n        mocV1 = IMocV1(mocV1_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() external view returns (bool) {\n        IMocV1 moc = mocV1;\n        if (moc.paused()) return false;\n        return (moc.isBitProInterestEnabled());\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        mocV1.payBitProHoldersInterestPayment();\n    }\n}\n\ninterface IMocV1 {\n    function paused() external view returns (bool);\n    function isBitProInterestEnabled() external view returns (bool);\n    function payBitProHoldersInterestPayment() external;\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/interfaces/IMocRC20.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/**\n * @title IMocRC20\n * @notice Base Moc ERC20 Token Interface: burn, mint. It can be both Pegs and Collateral Tokens.\n */\ninterface IMocRC20 is IERC20Upgradeable {\n    /**\n     * @dev Creates `amount` new tokens for `to`.\n     * See {ERC20-_mint}.\n     */\n    function mint(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Burns a specific `amount` of tokens for `to`.\n     * See {ERC20-_burn}.\n     */\n    function burn(address to, uint256 amount) external;\n}\n"},{"file_path":"npm/@openzeppelin/contracts-upgradeable@4.9.3/token/ERC20/utils/SafeERC20Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n    using AddressUpgradeable for address;\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     */\n    function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n     * Revert on invalid signature.\n     */\n    function safePermit(\n        IERC20PermitUpgradeable token,\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal {\n        uint256 nonceBefore = token.nonces(owner);\n        token.permit(owner, spender, value, deadline, v, r, s);\n        uint256 nonceAfter = token.nonces(owner);\n        require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n        // and not revert is the subcall reverts.\n\n        (bool success, bytes memory returndata) = address(token).call(data);\n        return\n            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\n    }\n}\n"},{"file_path":"npm/@uniswap/v3-core@1.0.1/contracts/interfaces/callback/IUniswapV3SwapCallback.sol","source_code":"// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Callback for IUniswapV3PoolActions#swap\n/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface\ninterface IUniswapV3SwapCallback {\n    /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.\n    /// @dev In the implementation you must pay the pool tokens owed for the swap.\n    /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.\n    /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.\n    /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by\n    /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.\n    /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by\n    /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.\n    /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call\n    function uniswapV3SwapCallback(\n        int256 amount0Delta,\n        int256 amount1Delta,\n        bytes calldata data\n    ) external;\n}\n"},{"file_path":"npm/@openzeppelin/contracts@4.9.3/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"},{"file_path":"npm/main-sc-protocol-v2@3.0.9/contracts/interfaces/IMocQueue.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\ninterface IMocQueue {\n    function mocMultiCollateralGuard() external view returns (address);\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/v3/TaskUpdateEmaV3.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../ITask.sol\";\nimport { MocOperations } from \"@moc/moc-main/contracts/core/MocOperations.sol\";\nimport { Utils } from \"../Utils.sol\";\n\n/**\n * @title TaskUpdateEmaV3\n * @notice This contract implements a task that updates the TPs moving average.\n */\ncontract TaskUpdateEmaV3 is ITask {\n    MocOperations public immutable bucket;\n\n    /**\n     * @notice Constructor\n     * @param bucket_ The address of the MocOperations contract.\n     */\n    constructor(address bucket_) {\n        bucket = MocOperations(bucket_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() external view returns (bool) {\n        MocOperations bucket_ = bucket;\n        bool areValidPrices = Utils._areValidPrices(address(bucket_));\n        if (!areValidPrices || bucket_.liquidated()) return false;\n        return bucket_.shouldCalculateEma();\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        bucket.updateEmas();\n    }\n}\n"},{"file_path":"npm/@moneyonchain/oracles@3.0.10/contracts/tasks/v1/TaskUpdateEmaV1.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { ITask } from \"../../ITask.sol\";\nimport { Utils } from \"../Utils.sol\";\n\n/**\n * @title TaskUpdateEmaV1\n * @notice This contract implements a task that updates the Bitcoin moving average.\n */\ncontract TaskUpdateEmaV1 is ITask {\n    IMocStateV1 public immutable mocStateV1;\n\n    /**\n     * @notice Constructor\n     * @param mocStateV1_ The address of the MocState contract.\n     */\n    constructor(address mocStateV1_) {\n        mocStateV1 = IMocStateV1(mocStateV1_);\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function checkTask() external view returns (bool) {\n        if (!Utils._isValidPrice((mocStateV1.getBtcPriceProvider()))) return false;\n        return mocStateV1.shouldCalculateEma();\n    }\n\n    /**\n     * @inheritdoc ITask\n     */\n    function runTask() external {\n        mocStateV1.calculateBitcoinMovingAverage();\n    }\n}\n\ninterface IMocStateV1 {\n    function getBtcPriceProvider() external view returns (address);\n    function shouldCalculateEma() external view returns (bool);\n    function calculateBitcoinMovingAverage() external;\n}"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"qACsent_","type":"uint256"},{"internalType":"uint256","name":"qACNeeded_","type":"uint256"}],"name":"InsufficientQacSent","type":"error"},{"inputs":[{"internalType":"uint256","name":"qTCsent_","type":"uint256"},{"internalType":"uint256","name":"qTCNeeded_","type":"uint256"}],"name":"InsufficientQtcSent","type":"error"},{"inputs":[{"internalType":"uint256","name":"qTC_","type":"uint256"},{"internalType":"uint256","name":"tcAvailableToRedeem_","type":"uint256"}],"name":"InsufficientTCtoRedeem","type":"error"},{"inputs":[{"internalType":"uint256","name":"qTP_","type":"uint256"},{"internalType":"uint256","name":"tpAvailableToMint_","type":"uint256"}],"name":"InsufficientTPtoMint","type":"error"},{"inputs":[{"internalType":"uint256","name":"qTP_","type":"uint256"},{"internalType":"uint256","name":"tpAvailableToRedeem_","type":"uint256"}],"name":"InsufficientTPtoRedeem","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidFluxCapacitorOperation","type":"error"},{"inputs":[],"name":"InvalidValue","type":"error"},{"inputs":[],"name":"Liquidated","type":"error"},{"inputs":[],"name":"LowCombinedCoverage","type":"error"},{"inputs":[{"internalType":"uint256","name":"cglb_","type":"uint256"},{"internalType":"uint256","name":"covThrld_","type":"uint256"}],"name":"LowCoverage","type":"error"},{"inputs":[{"internalType":"uint256","name":"max_","type":"uint256"},{"internalType":"uint256","name":"new_","type":"uint256"}],"name":"MaxFluxCapacitorOperationReached","type":"error"},{"inputs":[{"internalType":"address","name":"dataProviderAddress_","type":"address"}],"name":"MissingProviderData","type":"error"},{"inputs":[{"internalType":"address","name":"priceProviderAddress_","type":"address"}],"name":"MissingProviderPrice","type":"error"},{"inputs":[],"name":"MissingTimeToSettlement","type":"error"},{"inputs":[],"name":"MissingTimeToTCInterestPayment","type":"error"},{"inputs":[],"name":"NotAuthorizedChanger","type":"error"},{"inputs":[],"name":"NotWhenPaused","type":"error"},{"inputs":[],"name":"OnlyMultiCollateralGuard","type":"error"},{"inputs":[],"name":"OnlyPauser","type":"error"},{"inputs":[],"name":"OnlyQueue","type":"error"},{"inputs":[],"name":"OnlyWhenLastBucket","type":"error"},{"inputs":[],"name":"OnlyWhenLiquidated","type":"error"},{"inputs":[],"name":"OnlyWhilePaused","type":"error"},{"inputs":[],"name":"PeggedTokenAlreadyAdded","type":"error"},{"inputs":[{"internalType":"uint256","name":"qACmin_","type":"uint256"},{"internalType":"uint256","name":"qACtoRedeem_","type":"uint256"}],"name":"QacBelowMinimumRequired","type":"error"},{"inputs":[],"name":"QacNeededMustBeGreaterThanZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"qTCmin_","type":"uint256"},{"internalType":"uint256","name":"qTC_","type":"uint256"}],"name":"QtcBelowMinimumRequired","type":"error"},{"inputs":[{"internalType":"uint256","name":"qTPmin_","type":"uint256"},{"internalType":"uint256","name":"qTP_","type":"uint256"}],"name":"QtpBelowMinimumRequired","type":"error"},{"inputs":[],"name":"RecipientMustBeSender","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"Unstoppable","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tp_","type":"address"},{"indexed":true,"internalType":"address","name":"sender_","type":"address"},{"indexed":true,"internalType":"address","name":"recipient_","type":"address"},{"indexed":false,"internalType":"uint256","name":"qTP_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"qAC_","type":"uint256"}],"name":"LiqTPRedeemed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"i_","type":"uint256"},{"indexed":true,"internalType":"address","name":"tpTokenAddress_","type":"address"},{"components":[{"internalType":"address","name":"priceProviderAddress","type":"address"},{"internalType":"uint256","name":"tpCtarg","type":"uint256"},{"internalType":"uint256","name":"tpMintFee","type":"uint256"},{"internalType":"uint256","name":"tpRedeemFee","type":"uint256"},{"internalType":"uint256","name":"tpEma","type":"uint256"},{"internalType":"uint256","name":"tpEmaSf","type":"uint256"}],"indexed":false,"internalType":"struct PeggedTokenParams","name":"peggedTokenParams_","type":"tuple"}],"name":"PeggedTokenChange","type":"event"},{"anonymous":false,"inputs":[],"name":"SettlementExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"mocGain_","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"tpGain_","type":"uint256[]"}],"name":"SuccessFeeDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"interestAmount_","type":"uint256"}],"name":"TCInterestPayment","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"i_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldTPema_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTPema_","type":"uint256"}],"name":"TPemaUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"absoluteAccumulator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"},{"internalType":"uint256","name":"qTP_","type":"uint256"}],"name":"acceptRebalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IMocRC20","name":"tpToken_","type":"address"},{"components":[{"internalType":"address","name":"priceProviderAddress","type":"address"},{"internalType":"uint256","name":"tpCtarg","type":"uint256"},{"internalType":"uint256","name":"tpMintFee","type":"uint256"},{"internalType":"uint256","name":"tpRedeemFee","type":"uint256"},{"internalType":"uint256","name":"tpEma","type":"uint256"},{"internalType":"uint256","name":"tpEmaSf","type":"uint256"}],"internalType":"struct PeggedTokenParams","name":"peggedTokenParams_","type":"tuple"}],"name":"addPeggedToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"appreciationFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pACtps_","type":"uint256[]"}],"name":"calcCglb","outputs":[{"internalType":"uint256","name":"cglob","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pACtps_","type":"uint256[]"}],"name":"calcCglbAndLckAC","outputs":[{"internalType":"uint256","name":"cglob","type":"uint256"},{"internalType":"uint256","name":"lckAC","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pACtps_","type":"uint256[]"}],"name":"calcCtargemaCA","outputs":[{"internalType":"uint256","name":"ctargemaCA","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"},{"internalType":"uint256","name":"pACtp_","type":"uint256"}],"name":"calcCtargemaTP","outputs":[{"internalType":"uint256","name":"ctargemaTP","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pACtps_","type":"uint256[]"}],"name":"calcLckAC","outputs":[{"internalType":"uint256","name":"lckAC","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pACtps_","type":"uint256[]"}],"name":"calcLckACemaAdjusted","outputs":[{"internalType":"int256","name":"lckACemaAdjusted","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pACtps_","type":"uint256[]"}],"name":"calcPTCac","outputs":[{"internalType":"uint256","name":"pTCac","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pACtps_","type":"uint256[]"}],"name":"calcTCAvailableToRedeem","outputs":[{"internalType":"uint256","name":"tcAvailableToRedeem","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"},{"internalType":"uint256[]","name":"pACtps_","type":"uint256[]"}],"name":"calcTPAvailableToMint","outputs":[{"internalType":"int256","name":"tpAvailableToMintSigned","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IGovernor","name":"newGovernor_","type":"address"}],"name":"changeGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decayTimeSpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"differentialAccumulator","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IMocRC20","name":"tpToken_","type":"address"},{"components":[{"internalType":"address","name":"priceProviderAddress","type":"address"},{"internalType":"uint256","name":"tpCtarg","type":"uint256"},{"internalType":"uint256","name":"tpMintFee","type":"uint256"},{"internalType":"uint256","name":"tpRedeemFee","type":"uint256"},{"internalType":"uint256","name":"tpEma","type":"uint256"},{"internalType":"uint256","name":"tpEmaSf","type":"uint256"}],"internalType":"struct PeggedTokenParams","name":"peggedTokenParams_","type":"tuple"}],"name":"editPeggedToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emaCalculationTimeSpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"qTC","type":"uint256"},{"internalType":"uint256","name":"qACmax","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"vendor","type":"address"}],"internalType":"struct MocCore.MintTCParams","name":"params_","type":"tuple"}],"name":"execMintTC","outputs":[{"internalType":"uint256","name":"qACtotalNeeded","type":"uint256"},{"components":[{"internalType":"uint256","name":"qACFee","type":"uint256"},{"internalType":"uint256","name":"qFeeToken","type":"uint256"},{"internalType":"uint256","name":"qACVendorMarkup","type":"uint256"},{"internalType":"uint256","name":"qFeeTokenVendorMarkup","type":"uint256"}],"internalType":"struct MocCommons.FeeCalcs","name":"feeCalcs","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tp","type":"address"},{"internalType":"uint256","name":"qTP","type":"uint256"},{"internalType":"uint256","name":"qACmax","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"vendor","type":"address"}],"internalType":"struct MocCommons.MintTCandTPParams","name":"params_","type":"tuple"}],"name":"execMintTCandTP","outputs":[{"internalType":"uint256","name":"qACtoMintTC","type":"uint256"},{"internalType":"uint256","name":"qACtoMintTP","type":"uint256"},{"internalType":"uint256","name":"qACtoSpent","type":"uint256"},{"internalType":"uint256","name":"qTCMinted","type":"uint256"},{"components":[{"internalType":"uint256","name":"qACFee","type":"uint256"},{"internalType":"uint256","name":"qFeeToken","type":"uint256"},{"internalType":"uint256","name":"qACVendorMarkup","type":"uint256"},{"internalType":"uint256","name":"qFeeTokenVendorMarkup","type":"uint256"}],"internalType":"struct MocCommons.FeeCalcs","name":"feeCalcs","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tp","type":"address"},{"internalType":"uint256","name":"qTP","type":"uint256"},{"internalType":"uint256","name":"qACmax","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"vendor","type":"address"}],"internalType":"struct MocCore.MintTPParams","name":"params_","type":"tuple"}],"name":"execMintTP","outputs":[{"internalType":"uint256","name":"qACtotalNeeded","type":"uint256"},{"components":[{"internalType":"uint256","name":"qACFee","type":"uint256"},{"internalType":"uint256","name":"qFeeToken","type":"uint256"},{"internalType":"uint256","name":"qACVendorMarkup","type":"uint256"},{"internalType":"uint256","name":"qFeeTokenVendorMarkup","type":"uint256"}],"internalType":"struct MocCommons.FeeCalcs","name":"feeCalcs","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"qTC","type":"uint256"},{"internalType":"uint256","name":"qACmin","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"vendor","type":"address"}],"internalType":"struct MocCore.RedeemTCParams","name":"params_","type":"tuple"}],"name":"execRedeemTC","outputs":[{"internalType":"uint256","name":"qACtoRedeem","type":"uint256"},{"components":[{"internalType":"uint256","name":"qACFee","type":"uint256"},{"internalType":"uint256","name":"qFeeToken","type":"uint256"},{"internalType":"uint256","name":"qACVendorMarkup","type":"uint256"},{"internalType":"uint256","name":"qFeeTokenVendorMarkup","type":"uint256"}],"internalType":"struct MocCommons.FeeCalcs","name":"feeCalcs","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tp","type":"address"},{"internalType":"uint256","name":"qTC","type":"uint256"},{"internalType":"uint256","name":"qTP","type":"uint256"},{"internalType":"uint256","name":"qACmin","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"vendor","type":"address"}],"internalType":"struct MocCommons.RedeemTCandTPParams","name":"params_","type":"tuple"}],"name":"execRedeemTCandTP","outputs":[{"internalType":"uint256","name":"qACtoRedeemTC","type":"uint256"},{"internalType":"uint256","name":"qACtoRedeemTP","type":"uint256"},{"internalType":"uint256","name":"qACtoReceive","type":"uint256"},{"internalType":"uint256","name":"qTCRedeemed","type":"uint256"},{"components":[{"internalType":"uint256","name":"qACFee","type":"uint256"},{"internalType":"uint256","name":"qFeeToken","type":"uint256"},{"internalType":"uint256","name":"qACVendorMarkup","type":"uint256"},{"internalType":"uint256","name":"qFeeTokenVendorMarkup","type":"uint256"}],"internalType":"struct MocCommons.FeeCalcs","name":"feeCalcs","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tp","type":"address"},{"internalType":"uint256","name":"qTP","type":"uint256"},{"internalType":"uint256","name":"qACmin","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"vendor","type":"address"}],"internalType":"struct MocCommons.RedeemTPParams","name":"params_","type":"tuple"}],"name":"execRedeemTP","outputs":[{"internalType":"uint256","name":"qACtoRedeem","type":"uint256"},{"components":[{"internalType":"uint256","name":"qACFee","type":"uint256"},{"internalType":"uint256","name":"qFeeToken","type":"uint256"},{"internalType":"uint256","name":"qACVendorMarkup","type":"uint256"},{"internalType":"uint256","name":"qFeeTokenVendorMarkup","type":"uint256"}],"internalType":"struct MocCommons.FeeCalcs","name":"feeCalcs","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"execSettlement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tp","type":"address"},{"internalType":"uint256","name":"qTC","type":"uint256"},{"internalType":"uint256","name":"qTPmin","type":"uint256"},{"internalType":"uint256","name":"qACmax","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"vendor","type":"address"}],"internalType":"struct MocCommons.SwapTCforTPParams","name":"params_","type":"tuple"}],"name":"execSwapTCforTP","outputs":[{"internalType":"uint256","name":"qTPMinted","type":"uint256"},{"components":[{"internalType":"uint256","name":"qACFee","type":"uint256"},{"internalType":"uint256","name":"qFeeToken","type":"uint256"},{"internalType":"uint256","name":"qACVendorMarkup","type":"uint256"},{"internalType":"uint256","name":"qFeeTokenVendorMarkup","type":"uint256"}],"internalType":"struct MocCommons.FeeCalcs","name":"feeCalcs","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tp","type":"address"},{"internalType":"uint256","name":"qTP","type":"uint256"},{"internalType":"uint256","name":"qTCmin","type":"uint256"},{"internalType":"uint256","name":"qACmax","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"vendor","type":"address"}],"internalType":"struct MocCommons.SwapTPforTCParams","name":"params_","type":"tuple"}],"name":"execSwapTPforTC","outputs":[{"internalType":"uint256","name":"qTCMinted","type":"uint256"},{"components":[{"internalType":"uint256","name":"qACFee","type":"uint256"},{"internalType":"uint256","name":"qFeeToken","type":"uint256"},{"internalType":"uint256","name":"qACVendorMarkup","type":"uint256"},{"internalType":"uint256","name":"qFeeTokenVendorMarkup","type":"uint256"}],"internalType":"struct MocCommons.FeeCalcs","name":"feeCalcs","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tpFrom","type":"address"},{"internalType":"address","name":"tpTo","type":"address"},{"internalType":"uint256","name":"qTP","type":"uint256"},{"internalType":"uint256","name":"qTPmin","type":"uint256"},{"internalType":"uint256","name":"qACmax","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"vendor","type":"address"}],"internalType":"struct MocCommons.SwapTPforTPParams","name":"params_","type":"tuple"}],"name":"execSwapTPforTP","outputs":[{"internalType":"uint256","name":"qTPMinted","type":"uint256"},{"components":[{"internalType":"uint256","name":"qACFee","type":"uint256"},{"internalType":"uint256","name":"qFeeToken","type":"uint256"},{"internalType":"uint256","name":"qACVendorMarkup","type":"uint256"},{"internalType":"uint256","name":"qFeeTokenVendorMarkup","type":"uint256"}],"internalType":"struct MocCommons.FeeCalcs","name":"feeCalcs","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeRetainer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeTokenPct","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeTokenPriceProvider","outputs":[{"internalType":"contract IPriceProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCglb","outputs":[{"internalType":"uint256","name":"cglob","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCtargemaCA","outputs":[{"internalType":"uint256","name":"ctargemaCA","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"}],"name":"getCtargemaTP","outputs":[{"internalType":"uint256","name":"ctargemaTP","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"useMaxLastPublicationBlock_","type":"bool"}],"name":"getLastPublicationBlock","outputs":[{"internalType":"uint256","name":"lastPublicationBlock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLckAC","outputs":[{"internalType":"uint256","name":"lckAC","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"i_","type":"uint256"}],"name":"getLckACByTP","outputs":[{"internalType":"uint256","name":"lckAC","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"}],"name":"getNTP","outputs":[{"internalType":"uint256","name":"nTP","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"}],"name":"getPACtp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPACtps","outputs":[{"internalType":"uint256[]","name":"pACtps","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPTCac","outputs":[{"internalType":"uint256","name":"pTCac","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTCAvailableToRedeem","outputs":[{"internalType":"uint256","name":"tcAvailableToRedeem","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"}],"name":"getTPAvailableToMint","outputs":[{"internalType":"int256","name":"tpAvailableToMintSigned","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalACavailable","outputs":[{"internalType":"uint256","name":"totalACavailable","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTpAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"contract IGovernor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"components":[{"internalType":"address payable","name":"mocQueueAddress","type":"address"},{"internalType":"address","name":"feeTokenAddress","type":"address"},{"internalType":"address","name":"feeTokenPriceProviderAddress","type":"address"},{"internalType":"address","name":"tcTokenAddress","type":"address"},{"internalType":"address","name":"mocFeeFlowAddress","type":"address"},{"internalType":"address","name":"mocAppreciationBeneficiaryAddress","type":"address"},{"internalType":"uint256","name":"protThrld","type":"uint256"},{"internalType":"uint256","name":"liqThrld","type":"uint256"},{"components":[{"internalType":"uint256","name":"tcMintFee","type":"uint256"},{"internalType":"uint256","name":"tcRedeemFee","type":"uint256"},{"internalType":"uint256","name":"swapTPforTPFee","type":"uint256"},{"internalType":"uint256","name":"swapTPforTCFee","type":"uint256"},{"internalType":"uint256","name":"swapTCforTPFee","type":"uint256"},{"internalType":"uint256","name":"redeemTCandTPFee","type":"uint256"},{"internalType":"uint256","name":"mintTCandTPFee","type":"uint256"},{"internalType":"uint256","name":"feeRetainer","type":"uint256"},{"internalType":"uint256","name":"feeTokenPct","type":"uint256"}],"internalType":"struct MocBaseBucket.OperationsFeeParams","name":"operationsFeeParams","type":"tuple"},{"internalType":"uint256","name":"successFee","type":"uint256"},{"internalType":"uint256","name":"appreciationFactor","type":"uint256"},{"internalType":"uint256","name":"settlementTimeSpan","type":"uint256"},{"internalType":"address","name":"tcInterestCollectorAddress","type":"address"},{"internalType":"uint256","name":"tcInterestRate","type":"uint256"},{"internalType":"uint256","name":"tcInterestPaymentTimeSpan","type":"uint256"},{"internalType":"address","name":"maxAbsoluteOpProviderAddress","type":"address"},{"internalType":"address","name":"maxOpDiffProviderAddress","type":"address"},{"internalType":"uint256","name":"decayTimeSpan","type":"uint256"},{"internalType":"bool","name":"allowDifferentRecipient","type":"bool"}],"internalType":"struct MocBaseBucket.InitializeBaseBucketParams","name":"initializeBaseBucketParams","type":"tuple"},{"internalType":"address","name":"governorAddress","type":"address"},{"internalType":"address","name":"pauserAddress","type":"address"},{"internalType":"address","name":"mocCoreExpansion","type":"address"},{"internalType":"uint256","name":"emaCalculationTimeSpan","type":"uint256"},{"internalType":"address","name":"mocVendors","type":"address"}],"internalType":"struct MocCore.InitializeCoreParams","name":"initializeCoreParams","type":"tuple"},{"internalType":"address","name":"acTokenAddress","type":"address"}],"internalType":"struct MocCARC20.InitializeParams","name":"initializeParams_","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isLiquidationAvailable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isLiquidationReached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastOperationTimeStamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liqEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"},{"internalType":"address","name":"recipient_","type":"address"}],"name":"liqRedeemTP","outputs":[{"internalType":"uint256","name":"qACRedeemed","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"liqThrld","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"liquidated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"makeStoppable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"makeUnstoppable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxAbsoluteOpProvider","outputs":[{"internalType":"contract IDataProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxOpDiffProvider","outputs":[{"internalType":"contract IDataProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timeSpan_","type":"uint256"}],"name":"maxQACToMintTP","outputs":[{"internalType":"uint256","name":"maxQAC","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timeSpan_","type":"uint256"}],"name":"maxQACToRedeemTP","outputs":[{"internalType":"uint256","name":"maxQAC","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"qTC_","type":"uint256"},{"internalType":"uint256","name":"qACmax_","type":"uint256"},{"internalType":"address","name":"recipient_","type":"address"},{"internalType":"address","name":"vendor_","type":"address"}],"name":"mintTC","outputs":[{"internalType":"uint256","name":"operId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"},{"internalType":"uint256","name":"qTP_","type":"uint256"},{"internalType":"uint256","name":"qACmax_","type":"uint256"},{"internalType":"address","name":"recipient_","type":"address"},{"internalType":"address","name":"vendor_","type":"address"}],"name":"mintTCandTP","outputs":[{"internalType":"uint256","name":"operId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintTCandTPFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"},{"internalType":"uint256","name":"qTP_","type":"uint256"},{"internalType":"uint256","name":"qACmax_","type":"uint256"},{"internalType":"address","name":"recipient_","type":"address"},{"internalType":"address","name":"vendor_","type":"address"}],"name":"mintTP","outputs":[{"internalType":"uint256","name":"operId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mocAppreciationBeneficiaryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mocFeeFlowAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mocQueue","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mocVendors","outputs":[{"internalType":"contract MocVendors","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nACcb","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nTCcb","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextEmaCalculation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextSettlementTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextTCInterestPayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pegContainer","outputs":[{"internalType":"uint256","name":"nTP","type":"uint256"},{"internalType":"contract IPriceProvider","name":"priceProvider","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"peggedTokenIndex","outputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protThrld","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"qACLockedInPending","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"},{"internalType":"uint256","name":"qTP_","type":"uint256"},{"internalType":"uint256","name":"qAC_","type":"uint256"}],"name":"rebalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"qTC_","type":"uint256"},{"internalType":"uint256","name":"qACmin_","type":"uint256"},{"internalType":"address","name":"recipient_","type":"address"},{"internalType":"address","name":"vendor_","type":"address"}],"name":"redeemTC","outputs":[{"internalType":"uint256","name":"operId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"},{"internalType":"uint256","name":"qTC_","type":"uint256"},{"internalType":"uint256","name":"qTP_","type":"uint256"},{"internalType":"uint256","name":"qACmin_","type":"uint256"},{"internalType":"address","name":"recipient_","type":"address"},{"internalType":"address","name":"vendor_","type":"address"}],"name":"redeemTCandTP","outputs":[{"internalType":"uint256","name":"operId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"redeemTCandTPFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"},{"internalType":"uint256","name":"qTP_","type":"uint256"},{"internalType":"uint256","name":"qACmin_","type":"uint256"},{"internalType":"address","name":"recipient_","type":"address"},{"internalType":"address","name":"vendor_","type":"address"}],"name":"redeemTP","outputs":[{"internalType":"uint256","name":"operId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"refreshACBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"protThrld_","type":"uint256"},{"internalType":"uint256","name":"liqThrld_","type":"uint256"}],"name":"setCoverageThresholds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"timeSpan_","type":"uint256"}],"name":"setEmaCalculationTimeSpan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mocFeeTokenAddress_","type":"address"},{"internalType":"address","name":"mocFeeTokenPriceProviderAddress_","type":"address"}],"name":"setFeeTokenParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"maxAbsoluteOpProviderAddress_","type":"address"},{"internalType":"address","name":"maxOpDiffProviderAddress_","type":"address"},{"internalType":"uint256","name":"decayTimeSpan_","type":"uint256"}],"name":"setFluxCapacitorParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"liqEnabled_","type":"bool"}],"name":"setLiqEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setLiquidated","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mocCoreExpansion_","type":"address"}],"name":"setMocCoreExpansion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mocFeeFlowAddress_","type":"address"}],"name":"setMocFeeFlowAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"mocQueueAddress_","type":"address"}],"name":"setMocQueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mocVendors_","type":"address"}],"name":"setMocVendors","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"tcMintFee","type":"uint256"},{"internalType":"uint256","name":"tcRedeemFee","type":"uint256"},{"internalType":"uint256","name":"swapTPforTPFee","type":"uint256"},{"internalType":"uint256","name":"swapTPforTCFee","type":"uint256"},{"internalType":"uint256","name":"swapTCforTPFee","type":"uint256"},{"internalType":"uint256","name":"redeemTCandTPFee","type":"uint256"},{"internalType":"uint256","name":"mintTCandTPFee","type":"uint256"},{"internalType":"uint256","name":"feeRetainer","type":"uint256"},{"internalType":"uint256","name":"feeTokenPct","type":"uint256"}],"internalType":"struct MocBaseBucket.OperationsFeeParams","name":"operationsFeeParams_","type":"tuple"}],"name":"setOperationsFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPauser_","type":"address"}],"name":"setPauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"settlementTimeSpan_","type":"uint256"}],"name":"setSettlementTimeSpan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"successFee_","type":"uint256"},{"internalType":"uint256","name":"appreciationFactor_","type":"uint256"},{"internalType":"address","name":"mocAppreciationBeneficiaryAddress_","type":"address"}],"name":"setSuccessFeeParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tcInterestCollectorAddress_","type":"address"},{"internalType":"uint256","name":"tcInterestRate_","type":"uint256"},{"internalType":"uint256","name":"tcInterestPaymentTimeSpan_","type":"uint256"}],"name":"setTCInterestParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settlementTimeSpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"shouldCalculateEma","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stoppable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"successFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"},{"internalType":"uint256","name":"qTC_","type":"uint256"},{"internalType":"uint256","name":"qTPmin_","type":"uint256"},{"internalType":"uint256","name":"qACmax_","type":"uint256"},{"internalType":"address","name":"recipient_","type":"address"},{"internalType":"address","name":"vendor_","type":"address"}],"name":"swapTCforTP","outputs":[{"internalType":"uint256","name":"operId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"swapTCforTPFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tp_","type":"address"},{"internalType":"uint256","name":"qTP_","type":"uint256"},{"internalType":"uint256","name":"qTCmin_","type":"uint256"},{"internalType":"uint256","name":"qACmax_","type":"uint256"},{"internalType":"address","name":"recipient_","type":"address"},{"internalType":"address","name":"vendor_","type":"address"}],"name":"swapTPforTC","outputs":[{"internalType":"uint256","name":"operId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"swapTPforTCFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tpFrom_","type":"address"},{"internalType":"address","name":"tpTo_","type":"address"},{"internalType":"uint256","name":"qTP_","type":"uint256"},{"internalType":"uint256","name":"qTPmin_","type":"uint256"},{"internalType":"uint256","name":"qACmax_","type":"uint256"},{"internalType":"address","name":"recipient_","type":"address"},{"internalType":"address","name":"vendor_","type":"address"}],"name":"swapTPforTP","outputs":[{"internalType":"uint256","name":"operId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"swapTPforTPFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tcHoldersInterestPayment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tcInterestCollectorAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tcInterestPaymentTimeSpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tcInterestRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tcMintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tcRedeemFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tcToken","outputs":[{"internalType":"contract IMocRC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tpCtarg","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tpEma","outputs":[{"internalType":"uint256","name":"ema","type":"uint256"},{"internalType":"uint256","name":"sf","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tpLiqPrices","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tpMintFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tpRedeemFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tpTokens","outputs":[{"internalType":"contract IMocRC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"uint256","name":"qACToUnlock_","type":"uint256"}],"name":"unlockACInPending","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"uint256","name":"qTCToUnlock_","type":"uint256"}],"name":"unlockTCInPending","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"contract IERC20Upgradeable","name":"tpToken_","type":"address"},{"internalType":"uint256","name":"qTPToUnlock_","type":"uint256"}],"name":"unlockTPInPending","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateEmas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":true,"constructor_args":null}