{"file_path":"project/contracts/token/USDRIF/StableTokenV2.sol","creation_status":"success","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","deployed_bytecode":"0x60806040908082526004908136101561001757600080fd5b600092833560e01c91826301ffc9a7146112f45750816306fdde031461124d578163095ea7b3146112175781630c340a24146111ed57816318160ddd146111ce57816323b872dd146110fa578163248a9ca3146110ce5781632f2ff15d14611097578163313ce5671461107b57816336568abe14610fe8578382633659cfe614610f51575081633950935114610eff57816340c10f1914610e0f5781634f1ef28614610d5057816352d1902d14610c7c57816370a0823114610c4157816383d2230d14610b065781638f15b4141461062e5781639010d07c146105ec57816391d14854146105a057816395d89b41146104bd5781639dc29fac1461036f578163a217fddf14610354578163a457c2d7146102ab578163a9059cbb1461026b578163ca15c87314610242578163d547741f14610208578163dd62ed3e146101ae575063e4c0aaf41461016757600080fd5b346101aa5760203660031901126101aa57356001600160a01b038116908190036101aa57610193611d83565b61015f80546001600160a01b031916909117905580f35b5080fd5b919050346102045781600319360112610204576001600160a01b039035818116908190036102005760243591821680920361020057928291602094825260ca8552828220908252845220549051908152f35b8380fd5b8280fd5b905034610204573660031901126101aa57356024356001600160a01b0381168103610204578161023a61023f93611808565b61195e565b80f35b919050346102045760203660031901126102045760209282913581526097845220549051908152f35b9190503461020457816003193601126102045735916001600160a01b03831683036102a857506102a16020926024359033611680565b5160018152f35b80fd5b8284346102a857826003193601126102a8578135916001600160a01b038316918284036102a85784906024359333825260ca602052828220908252602052205490828210610303576020856102a1858503873361157e565b608490602086519162461bcd60e51b8352820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152fd5b8390346101aa57816003193601126101aa5751908152602090f35b8383346101aa57826003193601126101aa5780356001600160a01b038116919082900361020457602435906103c37f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848611c44565b82156104705782845260c9602052848420549082821061042257508184957fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9360209386885260c9855203818720558160cb540360cb5551908152a380f35b608490602087519162461bcd60e51b8352820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152fd5b608490602086519162461bcd60e51b8352820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152fd5b83346102a857806003193601126102a8578151908060cd54906104df8261145f565b80855291602091600191828116908115610573575060011461051b575b610517868861050d828903836113b1565b5191829182611385565b0390f35b935060cd84527f83978b4c69c48dd978ab43fe30f077615294f938fb7f936d9eb340e51ea7db2e5b8385106105605750505050810160200161050d82610517866104fc565b8054868601840152938201938101610543565b90506105179795508693506020925061050d94915060ff191682840152151560051b8201019294866104fc565b919050346102045781600319360112610204576024356001600160a01b03811691908290036102005760209360ff92849235825260658652828220908252855220541690519015158152f35b919050346102045781600319360112610204576020926106189135815260978452826024359120611ea6565b905491519160018060a01b039160031b1c168152f35b9050346102045760803660031901126102045767ffffffffffffffff918035838111610b02576106619036908301611441565b92602435818111610afe576106799036908401611441565b93604435916001600160a01b03918284168403610afa57606435928316809303610afa5787549660ff8860081c161595868097610aed575b8015610ad6575b15610a7c57600198878a60ff198316178c55610a6b575b506106f260ff8b5460081c166106e481611d23565b6106ed81611d23565b611d23565b8251848111610a58578061070760cc5461145f565b94601f958681116109e7575b506020908d878411600114610968579261095d575b5050600019600383901b1c1916908a1b1760cc555b815193841161094a575061075260cd5461145f565b8281116108e7575b5060209183116001146108625761081694939291899183610857575b5050600019600383901b1c191690871b1760cd555b6107a860ff885460081c1661079f81611d23565b6106e481611d23565b61015f80546001600160a01b03191690911790556107c681876118d1565b6107f0817f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66118d1565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8486118d1565b61081e578280f35b825461ff0019168355519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602090a138808280f35b015190503880610776565b60cd895293929187917f83978b4c69c48dd978ab43fe30f077615294f938fb7f936d9eb340e51ea7db2e90601f1983168b5b8181106108cf5750968361081698106108b6575b505050811b0160cd5561078b565b015160001960f88460031b161c191690553880806108a8565b8289015184558b959093019260209283019201610894565b60cd8a527f83978b4c69c48dd978ab43fe30f077615294f938fb7f936d9eb340e51ea7db2e8380860160051c82019260208710610941575b0160051c019089905b82811061093657505061075a565b8b8155018990610928565b9250819261091f565b634e487b7160e01b8a5260419052602489fd5b015190503880610728565b91908d9450601f19841660cc84527f47197230e1e4b29fc0bd84d7d78966c0925452aff72a2a121538b102457e9ebe935b8181106109cf575084116109b6575b505050811b0160cc5561073d565b015160001960f88460031b161c191690553880806109a8565b8284015185558f969094019360209384019301610999565b90915060cc8d527f47197230e1e4b29fc0bd84d7d78966c0925452aff72a2a121538b102457e9ebe8680850160051c82019260208610610a4f575b859493910160051c909101908d908f5b838210610a4157505050610713565b81558594508e91018f610a32565b92508192610a22565b634e487b7160e01b8b526041825260248bfd5b61ffff1916610101178a55386106cf565b608490602089519162461bcd60e51b8352820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152fd5b50303b1580156106b85750600160ff8a16146106b8565b50600160ff8a16106106b1565b8780fd5b8580fd5b8480fd5b905034610204576020366003190112610204578135906001600160a01b0382168203610200578380526065602052610b4360018286200154611c44565b610b4d82856118d1565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610b7883826118d1565b610ba37f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84893846118d1565b610bad338261195e565b610bb7338461195e565b610bc1338661195e565b848052609760205260018286205403610c2a57808552609760205260018286205403610c145750818452609760205260018185205403610bff578380f35b51630e2b37cd60e41b81529182015260249150fd5b83906024925191630e2b37cd60e41b8352820152fd5b8151630e2b37cd60e41b8152808501869052602490fd5b9190503461020457602036600319011261020457356001600160a01b03811690819003610204578282916020945260c9845220549051908152f35b8284346102a857806003193601126102a857507f0000000000000000000000006d1bb87856a2b2351d87ba5772a93dc911325af96001600160a01b03163003610ce857602082517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b6020608492519162461bcd60e51b8352820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152fd5b36600319011290506101aa5780356001600160a01b038082168203610200576024359167ffffffffffffffff8311610b025736602384011215610b0257610e02610da861023f95856024600197369301359101611405565b92807f0000000000000000000000006d1bb87856a2b2351d87ba5772a93dc911325af91690610dd982301415611499565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5416146114fa565b610e0a611d83565b6119e4565b905082346102a857816003193601126102a85782356001600160a01b03811691908290036102a857602435610e637f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6611c44565b8215610ebc57602080955081610e9c7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9360cb5461155b565b60cb5584845260c982528584208181540190558551908152a35160018152f35b835162461bcd60e51b8152602081870152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606490fd5b91905034610204578160031936011261020457356001600160a01b0381168082036102005790610f4a6020946102a19333825260ca875285822090825286528460243591205461155b565b903361157e565b915091346101aa5760203660031901126101aa576001600160a01b03929035838116810361020457610fb08461023f957f0000000000000000000000006d1bb87856a2b2351d87ba5772a93dc911325af91690610dd982301415611499565b610fb8611d83565b610fcd610fc4846113e9565b925192836113b1565b828252601f19610fdc846113e9565b013660208401376119e4565b8383346101aa57826003193601126101aa57602435906001600160a01b038216808303610200573303611020579061023f913561195e565b608490602085519162461bcd60e51b8352820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152fd5b8390346101aa57816003193601126101aa576020905160128152f35b905034610204573660031901126101aa57356024356001600160a01b038116810361020457816110c961023f93611808565b6118d1565b919050346102045760203660031901126102045781602093600192358152606585522001549051908152f35b8383346101aa5760603660031901126101aa5780356001600160a01b03818116939092908483036102a85760243593841684036102a857859060443595815260ca6020528181203382526020522054906000198203611162575b6020866102a1878787611680565b84821061118b5750918391611180602096956102a19503338361157e565b919394819350611154565b606490602087519162461bcd60e51b8352820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152fd5b8390346101aa57816003193601126101aa5760209060cb549051908152f35b8390346101aa57816003193601126101aa5761015f5490516001600160a01b039091168152602090f35b9190503461020457816003193601126102045735916001600160a01b03831683036102a857506102a1602092602435903361157e565b83346102a857806003193601126102a8578151908060cc549061126f8261145f565b80855291602091600191828116908115610573575060011461129c57610517868861050d828903836113b1565b935060cc84527f47197230e1e4b29fc0bd84d7d78966c0925452aff72a2a121538b102457e9ebe5b8385106112e15750505050810160200161050d82610517866104fc565b80548686018401529382019381016112c4565b84908434610204576020366003190112610204573563ffffffff60e01b81168091036102045760209250635a05180f60e01b8114908115611337575b5015158152f35b637965db0b60e01b811491508115611351575b5083611330565b6301ffc9a760e01b1490508361134a565b60005b8381106113755750506000910152565b8181015183820152602001611365565b604091602082526113a58151809281602086015260208686019101611362565b601f01601f1916010190565b90601f8019910116810190811067ffffffffffffffff8211176113d357604052565b634e487b7160e01b600052604160045260246000fd5b67ffffffffffffffff81116113d357601f01601f191660200190565b929192611411826113e9565b9161141f60405193846113b1565b82948184528183011161143c578281602093846000960137010152565b600080fd5b9080601f8301121561143c5781602061145c93359101611405565b90565b90600182811c9216801561148f575b602083101461147957565b634e487b7160e01b600052602260045260246000fd5b91607f169161146e565b156114a057565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608490fd5b1561150157565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608490fd5b9190820180921161156857565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0390811691821561162f57169182156115df5760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918360005260ca8252604060002085600052825280604060002055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b6001600160a01b0390811691821561179d571691821561174c57600082815260c96020526040812054918083106116f857604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef95876020965260c98652038282205586815220818154019055604051908152a3565b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b9081602091031261143c5751801515810361143c5790565b61015f546040805163d994d6d560e01b8152336004820152909291602090829060249082906001600160a01b03165afa9081156118c657600091611897575b50159081611868575b506118585750565b51631dd1b1b560e21b8152600490fd5b905060005260656020526001816000200154600052806000203360005260205260ff8160002054161538611850565b6118b9915060203d6020116118bf575b6118b181836113b1565b8101906117f0565b38611847565b503d6118a7565b83513d6000823e3d90fd5b9060406119109260009080825260656020528282209360018060a01b03169384835260205260ff838320541615611913575b8152609760205220611ed4565b50565b8082526065602052828220848352602052828220600160ff198254161790553384827f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8580a4611903565b9060406119109260009080825260656020528282209360018060a01b03169384835260205260ff838320541661199c575b8152609760205220611f5e565b808252606560205282822084835260205282822060ff1981541690553384827ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b8580a461198f565b909160ff7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435416600014611a1f5750611a1d9150611e04565b565b604080516352d1902d60e01b8152602094919392906001600160a01b038416908681600481855afa60009181611c15575b50611ab057855162461bcd60e51b815260048101889052602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608490fd5b9395929492937fc9f76b5ec45e5cdef99837d7b6d2467235c1df8933c8ca56df5c35afa2c7d44401611bbf57611ae586611e04565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a283511590811591611bb7575b50611b22575b50505050565b611ba393600080611b3360276113e9565b95611b40855197886113b1565b602787527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c86880152660819985a5b195960ca1b858801528581519101845af4913d15611bad573d611b94610fc4826113e9565b8152600081943d92013e612193565b5038808080611b1c565b5060609250612193565b905038611b16565b825162461bcd60e51b815260048101859052602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b9091508781813d8311611c3d575b611c2d81836113b1565b8101031261143c57519038611a50565b503d611c23565b80600052602060658152604060002033600052815260ff6040600020541615611c6b575050565b611d076048611d1f9383611c8d611cf895611c8760143361204e565b9361204e565b906040519586937f416363657373436f6e74726f6c3a206163636f756e742000000000000000000083860152611ccc8151809285603789019101611362565b8401917001034b99036b4b9b9b4b733903937b6329607d1b603784015283519384918785019101611362565b010360288101845201826113b1565b60405162461bcd60e51b815291829160048301611385565b0390fd5b15611d2a57565b60405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b61015f5460405163d994d6d560e01b815233600482015290602090829060249082906001600160a01b03165afa908115611df857600091611dd9575b5015611dc757565b604051631dd1b1b560e21b8152600490fd5b611df2915060203d6020116118bf576118b181836113b1565b38611dbf565b6040513d6000823e3d90fd5b803b15611e4b577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b03909216919091179055565b60405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b8054821015611ebe5760005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b91906001830160009082825280602052604082205415600014611f585784549468010000000000000000861015611f445783611f34611f1d886001604098999a01855584611ea6565b819391549060031b91821b91600019901b19161790565b9055549382526020522055600190565b634e487b7160e01b83526041600452602483fd5b50925050565b9060018201906000928184528260205260408420549081151560001461204757600019918083018181116120335782549084820191821161201f57808203611fea575b50505080548015611fd657820191611fb98383611ea6565b909182549160031b1b191690555582526020526040812055600190565b634e487b7160e01b86526031600452602486fd5b61200a611ffa611f1d9386611ea6565b90549060031b1c92839286611ea6565b90558652846020526040862055388080611fa1565b634e487b7160e01b88526011600452602488fd5b634e487b7160e01b87526011600452602487fd5b5050505090565b600182811b926001600160ff1b038116036115685760028301928381116115685761209161207b856113e9565b9461208960405196876113b1565b8086526113e9565b6020919085830190601f1901368237855115611ebe5760309053845160011015611ebe5760786021860153600181018091116115685791905b81831161211f575050506120db5790565b606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f8116601081101561217e57855185101561217e576f181899199a1a9b1b9c1cb0b131b232b360811b901a85850183015360041c928015612169576000190191906120ca565b60246000634e487b7160e01b81526011600452fd5b60246000634e487b7160e01b81526032600452fd5b919290156121f557508151156121a7575090565b3b156121b05790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156122085750805190602001fd5b60405162461bcd60e51b8152908190611d1f906004830161138556fea26469706673582212206c0ccf6443ee86a6e8cbf1f2d47ed91355a20604c7dc5b1034a80c950f6f3cde64736f6c63430008180033","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/@uniswap/swap-router-contracts@1.3.1/:@uniswap/v3-core/=npm/@uniswap/v3-core@1.0.1/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","npm/moc-main-latest@1.0.13/:@uniswap/swap-router-contracts/=npm/@uniswap/swap-router-contracts@1.3.1/","npm/moc-main-latest@1.0.13/:@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-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","project/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","project/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@4.9.3/","project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@4.9.3/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/","project/:moc-main-latest/=npm/moc-main-latest@1.0.13/"],"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-05-12T18:58:02.368028Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60a060405234620000495730608052620000186200004e565b620000226200004e565b60405161225a9081620000f88239608051818181610c9101528181610dac0152610f830152f35b600080fd5b60005460ff8160081c16620000a25760ff808216036200006b5750565b60ff90811916176000557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160ff8152a1565b60405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608490fdfe60806040908082526004908136101561001757600080fd5b600092833560e01c91826301ffc9a7146112f45750816306fdde031461124d578163095ea7b3146112175781630c340a24146111ed57816318160ddd146111ce57816323b872dd146110fa578163248a9ca3146110ce5781632f2ff15d14611097578163313ce5671461107b57816336568abe14610fe8578382633659cfe614610f51575081633950935114610eff57816340c10f1914610e0f5781634f1ef28614610d5057816352d1902d14610c7c57816370a0823114610c4157816383d2230d14610b065781638f15b4141461062e5781639010d07c146105ec57816391d14854146105a057816395d89b41146104bd5781639dc29fac1461036f578163a217fddf14610354578163a457c2d7146102ab578163a9059cbb1461026b578163ca15c87314610242578163d547741f14610208578163dd62ed3e146101ae575063e4c0aaf41461016757600080fd5b346101aa5760203660031901126101aa57356001600160a01b038116908190036101aa57610193611d83565b61015f80546001600160a01b031916909117905580f35b5080fd5b919050346102045781600319360112610204576001600160a01b039035818116908190036102005760243591821680920361020057928291602094825260ca8552828220908252845220549051908152f35b8380fd5b8280fd5b905034610204573660031901126101aa57356024356001600160a01b0381168103610204578161023a61023f93611808565b61195e565b80f35b919050346102045760203660031901126102045760209282913581526097845220549051908152f35b9190503461020457816003193601126102045735916001600160a01b03831683036102a857506102a16020926024359033611680565b5160018152f35b80fd5b8284346102a857826003193601126102a8578135916001600160a01b038316918284036102a85784906024359333825260ca602052828220908252602052205490828210610303576020856102a1858503873361157e565b608490602086519162461bcd60e51b8352820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152fd5b8390346101aa57816003193601126101aa5751908152602090f35b8383346101aa57826003193601126101aa5780356001600160a01b038116919082900361020457602435906103c37f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848611c44565b82156104705782845260c9602052848420549082821061042257508184957fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9360209386885260c9855203818720558160cb540360cb5551908152a380f35b608490602087519162461bcd60e51b8352820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152fd5b608490602086519162461bcd60e51b8352820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152fd5b83346102a857806003193601126102a8578151908060cd54906104df8261145f565b80855291602091600191828116908115610573575060011461051b575b610517868861050d828903836113b1565b5191829182611385565b0390f35b935060cd84527f83978b4c69c48dd978ab43fe30f077615294f938fb7f936d9eb340e51ea7db2e5b8385106105605750505050810160200161050d82610517866104fc565b8054868601840152938201938101610543565b90506105179795508693506020925061050d94915060ff191682840152151560051b8201019294866104fc565b919050346102045781600319360112610204576024356001600160a01b03811691908290036102005760209360ff92849235825260658652828220908252855220541690519015158152f35b919050346102045781600319360112610204576020926106189135815260978452826024359120611ea6565b905491519160018060a01b039160031b1c168152f35b9050346102045760803660031901126102045767ffffffffffffffff918035838111610b02576106619036908301611441565b92602435818111610afe576106799036908401611441565b93604435916001600160a01b03918284168403610afa57606435928316809303610afa5787549660ff8860081c161595868097610aed575b8015610ad6575b15610a7c57600198878a60ff198316178c55610a6b575b506106f260ff8b5460081c166106e481611d23565b6106ed81611d23565b611d23565b8251848111610a58578061070760cc5461145f565b94601f958681116109e7575b506020908d878411600114610968579261095d575b5050600019600383901b1c1916908a1b1760cc555b815193841161094a575061075260cd5461145f565b8281116108e7575b5060209183116001146108625761081694939291899183610857575b5050600019600383901b1c191690871b1760cd555b6107a860ff885460081c1661079f81611d23565b6106e481611d23565b61015f80546001600160a01b03191690911790556107c681876118d1565b6107f0817f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66118d1565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8486118d1565b61081e578280f35b825461ff0019168355519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602090a138808280f35b015190503880610776565b60cd895293929187917f83978b4c69c48dd978ab43fe30f077615294f938fb7f936d9eb340e51ea7db2e90601f1983168b5b8181106108cf5750968361081698106108b6575b505050811b0160cd5561078b565b015160001960f88460031b161c191690553880806108a8565b8289015184558b959093019260209283019201610894565b60cd8a527f83978b4c69c48dd978ab43fe30f077615294f938fb7f936d9eb340e51ea7db2e8380860160051c82019260208710610941575b0160051c019089905b82811061093657505061075a565b8b8155018990610928565b9250819261091f565b634e487b7160e01b8a5260419052602489fd5b015190503880610728565b91908d9450601f19841660cc84527f47197230e1e4b29fc0bd84d7d78966c0925452aff72a2a121538b102457e9ebe935b8181106109cf575084116109b6575b505050811b0160cc5561073d565b015160001960f88460031b161c191690553880806109a8565b8284015185558f969094019360209384019301610999565b90915060cc8d527f47197230e1e4b29fc0bd84d7d78966c0925452aff72a2a121538b102457e9ebe8680850160051c82019260208610610a4f575b859493910160051c909101908d908f5b838210610a4157505050610713565b81558594508e91018f610a32565b92508192610a22565b634e487b7160e01b8b526041825260248bfd5b61ffff1916610101178a55386106cf565b608490602089519162461bcd60e51b8352820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152fd5b50303b1580156106b85750600160ff8a16146106b8565b50600160ff8a16106106b1565b8780fd5b8580fd5b8480fd5b905034610204576020366003190112610204578135906001600160a01b0382168203610200578380526065602052610b4360018286200154611c44565b610b4d82856118d1565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610b7883826118d1565b610ba37f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84893846118d1565b610bad338261195e565b610bb7338461195e565b610bc1338661195e565b848052609760205260018286205403610c2a57808552609760205260018286205403610c145750818452609760205260018185205403610bff578380f35b51630e2b37cd60e41b81529182015260249150fd5b83906024925191630e2b37cd60e41b8352820152fd5b8151630e2b37cd60e41b8152808501869052602490fd5b9190503461020457602036600319011261020457356001600160a01b03811690819003610204578282916020945260c9845220549051908152f35b8284346102a857806003193601126102a857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163003610ce857602082517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b6020608492519162461bcd60e51b8352820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152fd5b36600319011290506101aa5780356001600160a01b038082168203610200576024359167ffffffffffffffff8311610b025736602384011215610b0257610e02610da861023f95856024600197369301359101611405565b92807f00000000000000000000000000000000000000000000000000000000000000001690610dd982301415611499565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5416146114fa565b610e0a611d83565b6119e4565b905082346102a857816003193601126102a85782356001600160a01b03811691908290036102a857602435610e637f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6611c44565b8215610ebc57602080955081610e9c7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9360cb5461155b565b60cb5584845260c982528584208181540190558551908152a35160018152f35b835162461bcd60e51b8152602081870152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606490fd5b91905034610204578160031936011261020457356001600160a01b0381168082036102005790610f4a6020946102a19333825260ca875285822090825286528460243591205461155b565b903361157e565b915091346101aa5760203660031901126101aa576001600160a01b03929035838116810361020457610fb08461023f957f00000000000000000000000000000000000000000000000000000000000000001690610dd982301415611499565b610fb8611d83565b610fcd610fc4846113e9565b925192836113b1565b828252601f19610fdc846113e9565b013660208401376119e4565b8383346101aa57826003193601126101aa57602435906001600160a01b038216808303610200573303611020579061023f913561195e565b608490602085519162461bcd60e51b8352820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152fd5b8390346101aa57816003193601126101aa576020905160128152f35b905034610204573660031901126101aa57356024356001600160a01b038116810361020457816110c961023f93611808565b6118d1565b919050346102045760203660031901126102045781602093600192358152606585522001549051908152f35b8383346101aa5760603660031901126101aa5780356001600160a01b03818116939092908483036102a85760243593841684036102a857859060443595815260ca6020528181203382526020522054906000198203611162575b6020866102a1878787611680565b84821061118b5750918391611180602096956102a19503338361157e565b919394819350611154565b606490602087519162461bcd60e51b8352820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152fd5b8390346101aa57816003193601126101aa5760209060cb549051908152f35b8390346101aa57816003193601126101aa5761015f5490516001600160a01b039091168152602090f35b9190503461020457816003193601126102045735916001600160a01b03831683036102a857506102a1602092602435903361157e565b83346102a857806003193601126102a8578151908060cc549061126f8261145f565b80855291602091600191828116908115610573575060011461129c57610517868861050d828903836113b1565b935060cc84527f47197230e1e4b29fc0bd84d7d78966c0925452aff72a2a121538b102457e9ebe5b8385106112e15750505050810160200161050d82610517866104fc565b80548686018401529382019381016112c4565b84908434610204576020366003190112610204573563ffffffff60e01b81168091036102045760209250635a05180f60e01b8114908115611337575b5015158152f35b637965db0b60e01b811491508115611351575b5083611330565b6301ffc9a760e01b1490508361134a565b60005b8381106113755750506000910152565b8181015183820152602001611365565b604091602082526113a58151809281602086015260208686019101611362565b601f01601f1916010190565b90601f8019910116810190811067ffffffffffffffff8211176113d357604052565b634e487b7160e01b600052604160045260246000fd5b67ffffffffffffffff81116113d357601f01601f191660200190565b929192611411826113e9565b9161141f60405193846113b1565b82948184528183011161143c578281602093846000960137010152565b600080fd5b9080601f8301121561143c5781602061145c93359101611405565b90565b90600182811c9216801561148f575b602083101461147957565b634e487b7160e01b600052602260045260246000fd5b91607f169161146e565b156114a057565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608490fd5b1561150157565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608490fd5b9190820180921161156857565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0390811691821561162f57169182156115df5760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918360005260ca8252604060002085600052825280604060002055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b6001600160a01b0390811691821561179d571691821561174c57600082815260c96020526040812054918083106116f857604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef95876020965260c98652038282205586815220818154019055604051908152a3565b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b9081602091031261143c5751801515810361143c5790565b61015f546040805163d994d6d560e01b8152336004820152909291602090829060249082906001600160a01b03165afa9081156118c657600091611897575b50159081611868575b506118585750565b51631dd1b1b560e21b8152600490fd5b905060005260656020526001816000200154600052806000203360005260205260ff8160002054161538611850565b6118b9915060203d6020116118bf575b6118b181836113b1565b8101906117f0565b38611847565b503d6118a7565b83513d6000823e3d90fd5b9060406119109260009080825260656020528282209360018060a01b03169384835260205260ff838320541615611913575b8152609760205220611ed4565b50565b8082526065602052828220848352602052828220600160ff198254161790553384827f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8580a4611903565b9060406119109260009080825260656020528282209360018060a01b03169384835260205260ff838320541661199c575b8152609760205220611f5e565b808252606560205282822084835260205282822060ff1981541690553384827ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b8580a461198f565b909160ff7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435416600014611a1f5750611a1d9150611e04565b565b604080516352d1902d60e01b8152602094919392906001600160a01b038416908681600481855afa60009181611c15575b50611ab057855162461bcd60e51b815260048101889052602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608490fd5b9395929492937fc9f76b5ec45e5cdef99837d7b6d2467235c1df8933c8ca56df5c35afa2c7d44401611bbf57611ae586611e04565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a283511590811591611bb7575b50611b22575b50505050565b611ba393600080611b3360276113e9565b95611b40855197886113b1565b602787527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c86880152660819985a5b195960ca1b858801528581519101845af4913d15611bad573d611b94610fc4826113e9565b8152600081943d92013e612193565b5038808080611b1c565b5060609250612193565b905038611b16565b825162461bcd60e51b815260048101859052602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b9091508781813d8311611c3d575b611c2d81836113b1565b8101031261143c57519038611a50565b503d611c23565b80600052602060658152604060002033600052815260ff6040600020541615611c6b575050565b611d076048611d1f9383611c8d611cf895611c8760143361204e565b9361204e565b906040519586937f416363657373436f6e74726f6c3a206163636f756e742000000000000000000083860152611ccc8151809285603789019101611362565b8401917001034b99036b4b9b9b4b733903937b6329607d1b603784015283519384918785019101611362565b010360288101845201826113b1565b60405162461bcd60e51b815291829160048301611385565b0390fd5b15611d2a57565b60405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b61015f5460405163d994d6d560e01b815233600482015290602090829060249082906001600160a01b03165afa908115611df857600091611dd9575b5015611dc757565b604051631dd1b1b560e21b8152600490fd5b611df2915060203d6020116118bf576118b181836113b1565b38611dbf565b6040513d6000823e3d90fd5b803b15611e4b577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b03909216919091179055565b60405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b8054821015611ebe5760005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b91906001830160009082825280602052604082205415600014611f585784549468010000000000000000861015611f445783611f34611f1d886001604098999a01855584611ea6565b819391549060031b91821b91600019901b19161790565b9055549382526020522055600190565b634e487b7160e01b83526041600452602483fd5b50925050565b9060018201906000928184528260205260408420549081151560001461204757600019918083018181116120335782549084820191821161201f57808203611fea575b50505080548015611fd657820191611fb98383611ea6565b909182549160031b1b191690555582526020526040812055600190565b634e487b7160e01b86526031600452602486fd5b61200a611ffa611f1d9386611ea6565b90549060031b1c92839286611ea6565b90558652846020526040862055388080611fa1565b634e487b7160e01b88526011600452602488fd5b634e487b7160e01b87526011600452602487fd5b5050505090565b600182811b926001600160ff1b038116036115685760028301928381116115685761209161207b856113e9565b9461208960405196876113b1565b8086526113e9565b6020919085830190601f1901368237855115611ebe5760309053845160011015611ebe5760786021860153600181018091116115685791905b81831161211f575050506120db5790565b606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f8116601081101561217e57855185101561217e576f181899199a1a9b1b9c1cb0b131b232b360811b901a85850183015360041c928015612169576000190191906120ca565b60246000634e487b7160e01b81526011600452fd5b60246000634e487b7160e01b81526032600452fd5b919290156121f557508151156121a7575090565b3b156121b05790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156122085750805190602001fd5b60405162461bcd60e51b8152908190611d1f906004830161138556fea26469706673582212206c0ccf6443ee86a6e8cbf1f2d47ed91355a20604c7dc5b1034a80c950f6f3cde64736f6c63430008180033","name":"StableTokenV2","is_blueprint":false,"license_type":"none","is_fully_verified":true,"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":"npm/moc-main-latest@1.0.13/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":"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/moc-main-latest@1.0.13/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/@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/moc-main-latest@1.0.13/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":"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/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/@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/@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":"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/moc-main-latest@1.0.13/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\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\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 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        uint256 maxOperPerBatch_,\n        bool useMaxLastPublicationBlock_\n    ) external initializer {\n        __MocUpgradable_init(governor_, pauser_);\n        __ReentrancyGuard_init();\n        __MocRebalancer_init(microLiquidationExecCost_, liquidationExecCost_, coinbaseExecFeeRecipient_);\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 execution fee to the recipient\n     * @dev reverts if coinbase transfer fails\n     * @param executionFee_ amount to transfer\n     */\n    function _payExecutionFee(uint256 executionFee_) 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 (executionFee_ > address(this).balance) executionFee_ = address(this).balance;\n        _coinbaseExecFeeTransfer(executionFee_);\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 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    // ------- 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        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 combinedCglb combined coverage [PREC]\n     * @return combinedCtargemaCA combined ctargemaCA [PREC]\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    )\n        external\n        returns (\n            uint256 combinedCglb,\n            uint256 combinedCtargemaCA,\n            uint256 realTCAvailableToRedeem,\n            uint256[] memory bucketPACtps\n        )\n    {\n        MocOperations[] memory bucketsArray = buckets;\n        uint256[][] memory bucketsPACtps = _getBucketsPACtps(bucketsArray);\n        uint256[] memory normalizationFactors = _calcNormalizationFactors(bucketsArray, bucketsPACtps);\n        _updatesCtargemaCA(bucketsArray);\n        return (\n            _calcCombinedCglb(bucketsArray, bucketsPACtps, normalizationFactors),\n            _calcCombinedCtargemaCA(bucketsArray, bucketsPACtps, normalizationFactors),\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 combinedCglb combined coverage [PREC]\n     * @return combinedCtargemaCA combined ctargemaCA [PREC]\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    )\n        external\n        returns (\n            uint256 combinedCglb,\n            uint256 combinedCtargemaCA,\n            uint256 realTPAvailableToMint,\n            uint256[] memory bucketPACtps\n        )\n    {\n        MocOperations[] memory bucketsArray = buckets;\n        uint256[][] memory bucketsPACtps = _getBucketsPACtps(bucketsArray);\n        uint256[] memory normalizationFactors = _calcNormalizationFactors(bucketsArray, bucketsPACtps);\n        _updatesCtargemaCA(bucketsArray);\n        return (\n            _calcCombinedCglb(bucketsArray, bucketsPACtps, normalizationFactors),\n            _calcCombinedCtargemaCA(bucketsArray, bucketsPACtps, normalizationFactors),\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 combinedCglb combined coverage [PREC]\n     * @return combinedCtargemaCA combined ctargemaCA [PREC]\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    )\n        external\n        returns (\n            uint256 combinedCglb,\n            uint256 combinedCtargemaCA,\n            uint256 realTCAvailableToRedeem,\n            uint256 realTPAvailableToMint,\n            uint256[] memory bucketPACtps\n        )\n    {\n        MocOperations[] memory bucketsArray = buckets;\n        uint256[][] memory bucketsPACtps = _getBucketsPACtps(bucketsArray);\n        uint256[] memory normalizationFactors = _calcNormalizationFactors(bucketsArray, bucketsPACtps);\n        _updatesCtargemaCA(bucketsArray);\n        return (\n            _calcCombinedCglb(bucketsArray, bucketsPACtps, normalizationFactors),\n            _calcCombinedCtargemaCA(bucketsArray, bucketsPACtps, normalizationFactors),\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 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 operExecuted) = MocQueue(bucketsArray[iBucket].mocQueue()).execute(\n                msg.sender,\n                remainingOperToExecute,\n                blocksSinceLastPublication\n            );\n            unchecked {\n                totalExecutionFee += executionFee;\n                remainingOperToExecute -= operExecuted;\n                bucketsCounter += 1;\n            }\n        }\n        _payExecutionFee(totalExecutionFee);\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, ) = MocQueue(liquidatedBucket_.mocQueue()).execute(\n            msg.sender,\n            maxOperPerBatch,\n            0 /*blocksSinceLastPublication; allow to execute everything*/\n        );\n\n        _payExecutionFee(totalExecutionFee);\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    // @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":"project/contracts/changers/mocVendorsUpgrade/MocVendorsUpgradeChanger.sol","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.24;\n\nimport { IChangeContract } from \"moc-main-latest/contracts/interfaces/IChangeContract.sol\";\nimport { MocVendors } from \"moc-main-latest/contracts/vendors/MocVendors.sol\";\n\n/**\n  @title MocVendorsUpgradeChanger\n  @notice This contract is a ChangeContract intended to be used when\n  upgrading a MOC UUPS contract, through the Moc upgradeability\n  system. This doesn't initialize the upgraded contract, that should be done extending\n  this one or taking it as a guide\n */\ncontract MocVendorsUpgradeChanger is IChangeContract {\n    MocVendors public immutable mocVendorsProxy;\n    address public immutable MocVendorsNewImplementation;\n    uint256 public immutable maxVendorMarkup;\n    address[] public vendors;\n\n    /** \n    @notice Constructor\n    @param mocVendorsProxy_ Address of the proxy to be upgraded\n    @param MocVendorsNewImplementation_ Address of the contract the proxy will delegate to\n    @param maxVendorMarkup_ The new maxVendorMarkup to be set in the new implementation\n  */\n    constructor(\n        MocVendors mocVendorsProxy_,\n        address MocVendorsNewImplementation_,\n        uint256 maxVendorMarkup_,\n        address[] memory vendors_\n    ) {\n        mocVendorsProxy = mocVendorsProxy_;\n        MocVendorsNewImplementation = MocVendorsNewImplementation_;\n        maxVendorMarkup = maxVendorMarkup_;\n        vendors = vendors_;\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    IMPORTANT: This function should not be overridden, you should only redefine\n    _beforeUpgrade and _afterUpgrade methods to use this template\n   */\n    function execute() external {\n        // Store the current markups of the vendors before the upgrade, to set them again after the upgrade\n        uint256 vendorsLength = vendors.length;\n        uint64[] memory markupBeforeUpgrade = new uint64[](vendorsLength);\n        for (uint256 i; i < vendorsLength; i++) {\n            uint256 currentMarkup = mocVendorsProxy.vendorMarkup(vendors[i]);\n            markupBeforeUpgrade[i] = uint64(currentMarkup > maxVendorMarkup ? maxVendorMarkup : currentMarkup);\n        }\n\n        _beforeUpgrade();\n        _upgrade();\n        _afterUpgrade();\n\n        // Set the same markups to the vendors that were set before the upgrade, capped by the new maxVendorMarkup\n        for (uint256 i; i < vendorsLength; i++) {\n            mocVendorsProxy.setVendorMarkup(vendors[i], markupBeforeUpgrade[i]);\n        }\n    }\n\n    /**\n    @notice Upgrade the proxy to the newImplementation\n    @dev IMPORTANT: This function should not be overridden\n   */\n    function _upgrade() internal {\n        mocVendorsProxy.upgradeTo(MocVendorsNewImplementation);\n    }\n\n    /**\n    @notice Intended to prepare the system for the upgrade\n    @dev This function can be overridden by child changers to upgrade contracts that\n    require some preparation before the upgrade\n   */\n    function _beforeUpgrade() internal {}\n\n    /**\n    @notice Intended to do the final tweaks after the upgrade, for example initialize the contract\n    @dev This function can be overridden by child changers to upgrade contracts that\n    require some changes after the upgrade\n   */\n    function _afterUpgrade() internal {\n        // Set the new maxVendorMarkup in the new implementation\n        mocVendorsProxy.setMaxMarkup(maxVendorMarkup);\n    }\n}\n"},{"file_path":"npm/moc-main-latest@1.0.13/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 InsufficientQtpSent(uint256 qTPsent_, uint256 qTPNeeded_);\n    error QacBelowMinimumRequired(uint256 qACmin_, uint256 qACtoRedeem_);\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 qFeeTokenTotalNeeded amount of Fee Token needed to pay fees and markup. 0 if pays with AC\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, uint256 qFeeTokenTotalNeeded, FeeCalcs memory feeCalcs) {\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                    qFeeTokenTotalNeeded = 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, qFeeTokenTotalNeeded, 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/@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/multiCollateralUpgrade/MultiCollateralUpgradeChanger.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\";\nimport { IPriceProvider } from \"moc-main-latest/contracts/interfaces/IPriceProvider.sol\";\nimport { IMocSwapper } from \"moc-main-latest/contracts/interfaces/IMocSwapper.sol\";\nimport { MocRif } from \"../../MocRif.sol\";\nimport { PeggedTokenParams } from \"moc-main-latest/contracts/core/MocCommons.sol\";\nimport { MocQueue } from \"moc-main-latest/contracts/queue/MocQueue.sol\";\nimport { MocMultiCollateralGuard } from \"moc-main-latest/contracts/multiCollateral/MocMultiCollateralGuard.sol\";\nimport { BucketParams } from \"moc-main-latest/contracts/multiCollateral/MocMultiCollateralBase.sol\";\nimport { MocRC20 } from \"moc-main-latest/contracts/tokens/MocRC20.sol\";\nimport { MocCARC20 } from \"moc-main-latest/contracts/collateral/rc20/MocCARC20.sol\";\n\n/**\n  @title MultiCollateralUpgradeChanger\n  @notice This contract is a ChangeContract intended to be used with Moc Aeropulus \n  governance system.\n  @dev 1. Upgrade MocRif to a new implementation with the multicollateral feature\n       2. Upgrade USDRif to a new implementation that supports multicollateral\n       3. Migrate MocQueueRif. A migration is needed because there are breaking changes\n            We are not enforcing that old queue is empty to execute this changer. We are gonna\n            manage that off-chain. If for any reason the queue is not empty, those pending operations\n            will be handled independently on a new changer.\n       4. Migrate time trackers that uses block.number to timestamps\n       5. Set the new price provider for USDRif that has the getLastPublicationBlock() function implemented\n       6. Add DOC bucket with USDRif pegged token to MocMultiCollateralGuard\n */\ncontract MultiCollateralUpgradeChanger is IChangeContract {\n    // ------- Custom Errors -------\n    error InvalidSetting();\n\n    // ------- Constants -------\n    bytes32 private constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n    bytes32 private constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n    // ------- Storage -------\n    // USDRIF proxy contract to be upgraded\n    MocRC20 public immutable usdRifProxy;\n    // address of the USDRIF implementation contract the proxy will delegate to\n    address public immutable usdRifNewImplementation;\n    // MocRif proxy contract to be upgraded\n    MocRif public immutable rifBucket;\n    // address of the MocRif implementation contract the proxy will delegate to\n    address public immutable mocRifImplementation;\n    // address of the new MocCoreExpansion contract implementation\n    address public immutable mocMocCoreExpansionImplementation;\n    // new MocQueueRif proxy contract\n    MocQueue public immutable newMocQueueRifProxy;\n    // MocMultiCollateralGuardProxy proxy contract\n    MocMultiCollateralGuard public immutable mocMultiCollateralGuardProxy;\n    // new rif/usd price provider\n    address public immutable newPriceProvider;\n    // block span in seconds\n    uint256 public blockSpan;\n    // DOC bucket (MocCARC20) to be added to MocMultiCollateralGuard\n    MocCARC20 public immutable docBucket;\n    // Rebalance params for RIF bucket\n    BucketParams public rifBucketParams;\n    // Rebalance params for DOC bucket\n    BucketParams public docBucketParams;\n    // MocSwapper for RIF/DOC pair (only one swapper needed for 2 buckets)\n    IMocSwapper public immutable rifDocMocSwapper;\n    // New protected threshold for RIF bucket\n    uint256 public immutable rifNewProtectedThrld;\n    // usdRif params for DOC bucket\n    PeggedTokenParams public usdRifParamsForDocBucket;\n\n    /** \n      @notice Constructor\n      @param rifBucket_ address of the proxy to be upgraded\n      @param mocRifImplementation_ address of the contract the proxy will delegate to\n      @param usdRifNewImplementation_ address of the TP contract the proxy will delegate to\n      @param mocMocCoreExpansionImplementation_ Address of the new MocCoreExpansion implementation\n      @param newMocQueueRifProxy_ address of the new MocQueue proxy\n      @param newPriceProvider_ address of the new price provider\n      @param blockSpan_ block span in seconds\n      @param docBucket_ address of the DOC bucket (MocCARC20) to be added to MocMultiCollateralGuard\n      @param rifBucketParams_ rebalance params for RIF bucket\n      @param docBucketParams_ rebalance params for DOC bucket\n      @param rifDocMocSwapper_ MocSwapper for RIF/DOC pair\n      @param rifNewProtectedThrld_ new protected threshold for RIF bucket [PREC]\n      @param usdRifParamsForDocBucket_ usdRif params for DOC bucket\n    */\n    constructor(\n        MocRif rifBucket_,\n        address mocRifImplementation_,\n        address usdRifNewImplementation_,\n        address mocMocCoreExpansionImplementation_,\n        MocQueue newMocQueueRifProxy_,\n        address newPriceProvider_,\n        uint256 blockSpan_,\n        MocCARC20 docBucket_,\n        BucketParams memory rifBucketParams_,\n        BucketParams memory docBucketParams_,\n        IMocSwapper rifDocMocSwapper_,\n        uint256 rifNewProtectedThrld_,\n        PeggedTokenParams memory usdRifParamsForDocBucket_\n    ) {\n        rifBucket = rifBucket_;\n        mocRifImplementation = mocRifImplementation_;\n        usdRifNewImplementation = usdRifNewImplementation_;\n        mocMocCoreExpansionImplementation = mocMocCoreExpansionImplementation_;\n        newMocQueueRifProxy = newMocQueueRifProxy_;\n        mocMultiCollateralGuardProxy = newMocQueueRifProxy.mocMultiCollateralGuard();\n        usdRifProxy = MocRC20(address(rifBucket.tpTokens(0)));\n        newPriceProvider = newPriceProvider_;\n        blockSpan = blockSpan_;\n        docBucket = docBucket_;\n        rifBucketParams = rifBucketParams_;\n        docBucketParams = docBucketParams_;\n        rifDocMocSwapper = rifDocMocSwapper_;\n        rifNewProtectedThrld = rifNewProtectedThrld_;\n        usdRifParamsForDocBucket = usdRifParamsForDocBucket_;\n\n        // reverts if some parameter is wrong\n        verifySettings();\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      IMPORTANT: This function should not be overridden, you should only redefine\n      _beforeUpgrade and _afterUpgrade methods to use this template\n    */\n    function execute() external {\n        _beforeUpgrade();\n        _upgrade();\n        _afterUpgrade();\n    }\n\n    /**\n      @notice Upgrade the proxy to the newImplementation\n      @dev IMPORTANT: This function should not be overridden\n    */\n    function _upgrade() internal {\n        rifBucket.upgradeTo(mocRifImplementation);\n        usdRifProxy.upgradeTo(usdRifNewImplementation);\n    }\n\n    /**\n      @notice Intended to prepare the system for the upgrade\n    */\n    function _beforeUpgrade() internal {\n        // Initialize new Rif MocQueue OperationId with current values, to maintain continuity\n        MocQueue legacyMocQueueRifProxy = MocQueue(rifBucket.mocQueue());\n        uint256 currentOperIdCount = legacyMocQueueRifProxy.operIdCount();\n        newMocQueueRifProxy.initOperId(currentOperIdCount, currentOperIdCount);\n    }\n\n    /**\n      @notice Intended to do the final tweaks after the upgrade, for example initialize the contract\n    */\n    function _afterUpgrade() internal {\n        //set new MocQueue to MocCore\n        rifBucket.setMocQueue(payable(address(newMocQueueRifProxy)));\n        // set new MocCoreExpansion to MocCore\n        rifBucket.setMocCoreExpansion(mocMocCoreExpansionImplementation);\n        // register MocCore on MocQueue\n        newMocQueueRifProxy.registerBucket(rifBucket);\n\n        // register RIF bucket (base bucket) on MocMultiCollateralGuard with empty swappers\n        IMocSwapper[] memory emptySwappers;\n        mocMultiCollateralGuardProxy.addBucket(rifBucket, rifBucketParams, emptySwappers);\n\n        // migrate block numbers to timestamps\n        uint256 nextEmaCalculation = convertNextBlockToTimestamp(rifBucket.nextEmaCalculation());\n        uint256 nextTCInterestPayment = convertNextBlockToTimestamp(rifBucket.nextTCInterestPayment());\n        uint256 nextSettlementTime = convertNextBlockToTimestamp(rifBucket.nextSettlementTime());\n        uint256 lastOperationTimeStamp = block.timestamp; // simplify the logic setting current timestamp\n\n        rifBucket.migrateTimestamps(\n            nextEmaCalculation,\n            nextTCInterestPayment,\n            nextSettlementTime,\n            lastOperationTimeStamp\n        );\n        rifBucket.setFluxCapacitorParams(\n            address(rifBucket.maxAbsoluteOpProvider()),\n            address(rifBucket.maxOpDiffProvider()),\n            rifBucket.decayTimeSpan() * blockSpan\n        );\n        rifBucket.setEmaCalculationTimeSpan(rifBucket.emaCalculationTimeSpan() * blockSpan);\n        rifBucket.setTCInterestParams(\n            rifBucket.tcInterestCollectorAddress(),\n            rifBucket.tcInterestRate(),\n            rifBucket.tcInterestPaymentTimeSpan() * blockSpan\n        );\n        rifBucket.setSettlementTimeSpan(rifBucket.settlementTimeSpan() * blockSpan);\n        rifBucket.setCoverageThresholds(rifNewProtectedThrld, rifBucket.liqThrld());\n\n        // edit USDRif pegged token to set the new price provider\n        (, uint256 emaSf) = rifBucket.tpEma(0);\n        PeggedTokenParams memory peggedTokenParams = PeggedTokenParams({\n            priceProviderAddress: newPriceProvider,\n            tpCtarg: rifBucket.tpCtarg(0),\n            tpMintFee: rifBucket.tpMintFees(address(usdRifProxy)),\n            tpRedeemFee: rifBucket.tpRedeemFees(address(usdRifProxy)),\n            tpEma: 0, // Emma is not editable, only initialized\n            tpEmaSf: emaSf\n        });\n        rifBucket.editPeggedToken(usdRifProxy, peggedTokenParams);\n\n        ///////////////////////////////////////////////////////////////\n        /////// BEGIN Add DOC bucket to MocMultiCollateralGuard ///////\n        ///////////////////////////////////////////////////////////////\n\n        // Doc bucket is deployed with no MocMultiCollateralGuard, set it\n        MocQueue(docBucket.mocQueue()).setMocMultiCollateralGuard(mocMultiCollateralGuardProxy);\n        // Doc bucket is deployed with no registered bucket, register it\n        MocQueue(docBucket.mocQueue()).registerBucket(docBucket);\n\n        // Add DOC bucket with USDRif pegged token to MocMultiCollateralGuard\n        docBucket.addPeggedToken(usdRifProxy, usdRifParamsForDocBucket);\n        // Grant MINTER and BURNER roles to the DOC bucket so it can mint/burn USDRif\n        usdRifProxy.grantRole(MINTER_ROLE, address(docBucket));\n        usdRifProxy.grantRole(BURNER_ROLE, address(docBucket));\n\n        // Register DOC bucket on MocMultiCollateralGuard with the RIF/DOC swapper\n        IMocSwapper[] memory docSwappers = new IMocSwapper[](1);\n        docSwappers[0] = rifDocMocSwapper;\n        mocMultiCollateralGuardProxy.addBucket(docBucket, docBucketParams, docSwappers);\n\n        // reverts if some parameter is wrong\n        verifySettings();\n    }\n\n    /** \n    @notice convert next block to next timestamp\n    @param nextBlock_ next block to convert\n    @return nextTimestamp_ next timestamp\n  */\n    function convertNextBlockToTimestamp(uint256 nextBlock_) public view returns (uint256 nextTimestamp_) {\n        if (block.number >= nextBlock_) return block.timestamp;\n        uint256 remainingBlocks = nextBlock_ - block.number;\n        return block.timestamp + (remainingBlocks * blockSpan);\n    }\n\n    /**\n      @notice verifies the most importat the configuration params. Reverts if somethings is wrong\n    */\n    function verifySettings() public view {\n        address governor = address(rifBucket.governor());\n        address pauser = rifBucket.pauser();\n        // verify governor\n        if (governor != address(newMocQueueRifProxy.governor())) revert InvalidSetting();\n        if (governor != address(mocMultiCollateralGuardProxy.governor())) revert InvalidSetting();\n        if (governor != address(docBucket.governor())) revert InvalidSetting();\n        if (governor != address(MocQueue(docBucket.mocQueue()).governor())) revert InvalidSetting();\n\n        // verify pauser\n        if (pauser != newMocQueueRifProxy.pauser()) revert InvalidSetting();\n        if (pauser != mocMultiCollateralGuardProxy.pauser()) revert InvalidSetting();\n        if (pauser != docBucket.pauser()) revert InvalidSetting();\n        if (pauser != MocQueue(docBucket.mocQueue()).pauser()) revert InvalidSetting();\n\n        // verify new price provider implements getLastPublicationBlock()\n        IPriceProvider(newPriceProvider).getLastPublicationBlock();\n    }\n}\n"},{"file_path":"npm/moc-main-latest@1.0.13/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/@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/moc-main-latest@1.0.13/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/@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/@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/@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/moc-main-latest@1.0.13/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-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/moc-main-latest@1.0.13/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/@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/moc-main-latest@1.0.13/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-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/moc-main-latest@1.0.13/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/moc-main-latest@1.0.13/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 combinedCglb combined coverage [PREC]\n     * @return combinedCtargemaCA combined ctargemaCA [PREC]\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    )\n        external\n        returns (\n            uint256 combinedCglb,\n            uint256 combinedCtargemaCA,\n            uint256 realTCAvailableToRedeem,\n            uint256[] memory bucketPACtps\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 combinedCglb combined coverage [PREC]\n     * @return combinedCtargemaCA combined ctargemaCA [PREC]\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    )\n        external\n        returns (\n            uint256 combinedCglb,\n            uint256 combinedCtargemaCA,\n            uint256 realTPAvailableToMint,\n            uint256[] memory bucketPACtps\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 combinedCglb combined coverage [PREC]\n     * @return combinedCtargemaCA combined ctargemaCA [PREC]\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    )\n        external\n        returns (\n            uint256 combinedCglb,\n            uint256 combinedCtargemaCA,\n            uint256 realTCAvailableToRedeem,\n            uint256 realTPAvailableToMint,\n            uint256[] memory bucketPACtps\n        );\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":"npm/moc-main-latest@1.0.13/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_) internal view returns (uint256 ctargemaTP) {\n        uint256 auxTPctarg = tpCtarg[i_];\n        uint256 auxTpEma = tpEma[i_].ema;\n        if (shouldCalculateEma()) auxTpEma = _calcNewEma(tpEma[i_], pACtp_);\n        if (auxTpEma >= pACtp_) return auxTPctarg;\n        // [PREC] = [PREC] * [PREC] / [PREC]\n        return (auxTPctarg * pACtp_) / auxTpEma;\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 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) * 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 (protThrld * 2);\n            }\n        }\n        // [PREC] = ([PREC]^2) / [PREC]\n        ctargemaCA = num / den;\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     * @param pACtps_ All tps prices [PREC]\n     */\n    function _updateEmas(uint256[] memory pACtps_) internal {\n        if (shouldCalculateEma()) {\n            uint256 pegAmount = pegContainer.length;\n            for (uint256 i = 0; i < pegAmount; i = unchecked_inc(i)) {\n                _updateTPema(i, pACtps_[i]);\n            }\n            _updateNextEmaCalculation(emaCalculationTimeSpan);\n        }\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));\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_);\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() public {\n        _updateEmas(_getPACtps());\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/moc-main-latest@1.0.13/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 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    /**\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":"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    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    }\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":"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/moc-main-latest@1.0.13/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/moc-main-latest@1.0.13/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/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/moc-main-latest@1.0.13/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/moc-main-latest@1.0.13/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/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/@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":"npm/moc-main-latest@1.0.13/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/moc-main-latest@1.0.13/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\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        // 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/@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/moc-main-latest@1.0.13/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 CoinbaseExecFeePaymentFailed(uint256 executionFee_);\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 execution fee to the coinbaseExecFeeRecipient\n     * @dev emit CoinbaseExecFeePaymentFailed if the transfer fails\n     * @param executionFee_ amount of execution fee to transfer\n     */\n    function _coinbaseExecFeeTransfer(uint256 executionFee_) internal {\n        if (executionFee_ > 0) {\n            // solhint-disable-next-line avoid-low-level-calls\n            (bool success, ) = coinbaseExecFeeRecipient.call{ value: executionFee_ }(\"\");\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 CoinbaseExecFeePaymentFailed(executionFee_);\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            // 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            _coinbaseExecFeeTransfer(qACExecFee_);\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    // ------- 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        bool liqEnable = originBucket_.liqEnabled() && !originBucket_.liquidated();\n        if (liqEnable) {\n            return originBucket_.calcCglb(pACtps_) <= originBucket_.liqThrld();\n        }\n        return false;\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/moc-main-latest@1.0.13/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":"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/moc-main-latest@1.0.13/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/@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/moc-main-latest@1.0.13/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 { IPriceProvider } from \"../interfaces/IPriceProvider.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 qFeeTokenTotalNeeded amount of Fee Token used by `sender_` to pay fees. 0 if qAC is used instead\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            uint256 qFeeTokenTotalNeeded,\n            FeeCalcs memory feeCalcs\n        )\n    {\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, reverts if it's not\n        (uint256 lckAC, uint256 nACgain) = _evalCoverage(protThrld, pACtps);\n        (qTCtoMint, qACtoMintTC, qACtoMintTP) = _calcQACforMintTCandTP(\n            params_.qTP,\n            pACtp,\n            _getCtargemaTP(i, pACtp),\n            _getPTCac(lckAC, nACgain)\n        );\n        uint256 qACNeededtoMint = qACtoMintTC + qACtoMintTP;\n        uint256 qACSurcharges;\n        (qACSurcharges, qFeeTokenTotalNeeded, feeCalcs) = _calcFees(\n            params_.sender,\n            params_.vendor,\n            qACNeededtoMint,\n            mintTCandTPFee\n        );\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 qTP sent are insufficient.\n     * @param params_ redeem TC and TP function parameters\n     * @dev\n     *      i_ Pegged Token index\n     *      qTC_ amount of Collateral Token to redeem\n     *      qTP_ maximum 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 qTPtoRedeem amount of Pegged Token redeemed\n     * @return qFeeTokenTotalNeeded amount of Fee Token used by `sender_` to pay fees. 0 if qAC is used instead\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 qTPtoRedeem,\n            uint256 qFeeTokenTotalNeeded,\n            FeeCalcs memory feeCalcs\n        )\n    {\n        // emas are updated here\n        (uint256 combinedCglb, uint256 combinedCtargemaCA, uint256[] memory pACtps) = _getMocMultiCollateralGuard()\n            .getCombinedValues(address(this));\n\n        uint256 i = _tpi(params_.tp);\n        uint256 pACtp = pACtps[i];\n        _updateTPtracking(i, pACtp);\n        // evaluates that the system is not below the liquidation threshold\n        // one of the reasons is to prevent it from failing due to underflow because the lckAC > totalACavailable\n        (uint256 lckAC, uint256 nACgain) = _evalCoverage(liqThrld, pACtps);\n        uint256 pTCac = _getPTCac(lckAC, nACgain);\n        // ctargemaCA and ctargemaTP never should be less than ONE\n        // [PREC] = [PREC - PREC] * [PREC - PREC] / [PREC - PREC]\n        uint256 redeemProportion = ((combinedCglb - ONE) * (_getCtargemaTP(i, pACtp) - ONE)) /\n            (combinedCtargemaCA - ONE);\n        // calculate how many TP are needed to redeem TC and not compromise the coverage\n        // [N] = [N] * [PREC] * [PREC] / [PREC] * [PREC]\n        qTPtoRedeem = (params_.qTC * pACtp * pTCac) / (redeemProportion * PRECISION);\n        if (qTPtoRedeem > params_.qTP) revert InsufficientQtpSent(params_.qTP, qTPtoRedeem);\n        // if qTC == 0 => qTPtoRedeem == 0 and will revert because QacNeededMustBeGreaterThanZero\n        (qACtoRedeemTC, qACtoRedeemTP) = _calcQACforRedeemTCandTP(params_.qTC, qTPtoRedeem, pACtp, pTCac);\n        uint256 qACtotalToRedeem = qACtoRedeemTC + qACtoRedeemTP;\n        uint256 qACSurcharges;\n        (qACSurcharges, qFeeTokenTotalNeeded, feeCalcs) = _calcFees(\n            params_.sender,\n            params_.vendor,\n            qACtotalToRedeem,\n            redeemTCandTPFee\n        );\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(params_.qTC, qACtotalToRedeem);\n        _withdrawAndBurnTP(i, qTPtoRedeem, 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 qFeeTokenTotalNeeded amount of Fee Token used by `sender_` to pay fees. 0 if qAC is used instead\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    )\n        external\n        payable\n        returns (uint256 qACSurcharges, uint256 qTPtoMint, uint256 qFeeTokenTotalNeeded, FeeCalcs memory feeCalcs)\n    {\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        _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) > _getCtargemaTP(iFrom, pACtpFrom);\n        // if ctargemaTPto > ctargemaTPfrom we need to check coverage\n        if (ctargemaTPRelation) {\n            // emas are updated here\n            (\n                uint256 combinedCglb,\n                uint256 combinedCtargemaCA,\n                uint256 tpAvailableToMint,\n\n            ) = _getMocMultiCollateralGuard().getCombinedAndTP(address(this), params_.tpTo);\n            // evaluates whether or not the system coverage is healthy enough to mint TP\n            // evaluating the multi collateral status, reverts if it's not\n            _evalCombinedCoverage(combinedCglb, combinedCtargemaCA);\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, qFeeTokenTotalNeeded, feeCalcs) = _calcFees(\n            params_.sender,\n            params_.vendor,\n            qACtotalToRedeem,\n            swapTPforTPFee\n        );\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 qFeeTokenTotalNeeded amount of Fee Token used by `sender_` to pay fees. 0 if qAC is used instead\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    )\n        external\n        payable\n        returns (uint256 qACSurcharges, uint256 qTCtoMint, uint256 qFeeTokenTotalNeeded, FeeCalcs memory feeCalcs)\n    {\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, qFeeTokenTotalNeeded, feeCalcs) = _calcFees(\n            params_.sender,\n            params_.vendor,\n            qACtotalToRedeem,\n            swapTPforTCFee\n        );\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     * @return qFeeTokenTotalNeeded amount of Fee Token used by `sender_` to pay fees. 0 if qAC is used instead\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    )\n        external\n        payable\n        returns (uint256 qACSurcharges, uint256 qTPtoMint, uint256 qFeeTokenTotalNeeded, FeeCalcs memory feeCalcs)\n    {\n        // emas are updated here\n        (\n            uint256 combinedCglb,\n            uint256 combinedCtargemaCA,\n            uint256 tcAvailableToRedeem,\n            uint256 tpAvailableToMint,\n            uint256[] memory pACtps\n        ) = _getMocMultiCollateralGuard().getCombinedAndTCAndTP(address(this), params_.tp);\n        // evaluates whether or not the system coverage is healthy enough to redeem TC and mint TP\n        // evaluating the multi collateral status, reverts if it's not\n        _evalCombinedCoverage(combinedCglb, combinedCtargemaCA);\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, qFeeTokenTotalNeeded, feeCalcs) = _calcFees(\n            params_.sender,\n            params_.vendor,\n            qACtotalToRedeem,\n            swapTCforTPFee\n        );\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":"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":"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/@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/moc-main-latest@1.0.13/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/price-oracle-interfaces@0.0.1/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/@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/@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/price-oracle-interfaces@0.0.1/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/moc-main-latest@1.0.13/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/moc-main-latest@1.0.13/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_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 qTPRedeemed_ total amount of TP 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 qTPRedeemed_,\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            params_.qTC,\n            qTPRedeemed_,\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, uint256, 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, uint256, 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, uint256, 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, uint256, 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            uint256,\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 _qTPRedeemed,\n            uint256,\n            MocCore.FeeCalcs memory _feeCalcs\n        ) {\n            _onDeferredTCandTPRedeemed(\n                operId_,\n                params,\n                _qTPRedeemed,\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.InsufficientQtpSent.selector) {\n                emit OperationError(operId_, errorSelector, INSUFFICIENT_TP_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 (\n            uint256,\n            uint256 qTPMinted,\n            uint256,\n            MocCore.FeeCalcs memory feeCalcs\n        ) {\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 (\n            uint256,\n            uint256 qTCMinted,\n            uint256,\n            MocCore.FeeCalcs memory feeCalcs\n        ) {\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 (\n            uint256,\n            uint256 qTPMinted,\n            uint256,\n            MocCore.FeeCalcs memory feeCalcs\n        ) {\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 totalOperExecuted total amount of operations executed\n     */\n    function execute(\n        address executor_,\n        uint256 maxOperPerBatch_,\n        uint256 blocksSinceLastPublication_\n    ) external onlyMocMultiCollateralGuard returns (uint256 totalExecutionFee, uint256 totalOperExecuted) {\n        uint256 operId = firstOperId;\n        uint256 lastOperId;\n        uint256 limitBlk;\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            }\n        }\n        unchecked {\n            totalOperExecuted = operId - firstOperId;\n            totalExecutionFee = totalExecutionFee * _getBaseFee();\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/@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/@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":"npm/moc-main-latest@1.0.13/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     * @param qTPToLock_ TP amount to be locked\n     */\n    function _lockTPInPending(IERC20Upgradeable tpToken, uint256 qTPToLock_) internal {\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 qTP sent are insufficient.\n     * @param tp_ Pegged Token address\n     * @param qTC_ Maximum amount of Collateral Token to redeem\n     * @param qTP_ Maximum 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 qTP sent are insufficient.\n     * @param tp_ Pegged Token address\n     * @param qTC_ Maximum amount of Collateral Token to redeem\n     * @param qTP_ Maximum 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, uint256 qFeeTokenTotalNeeded, 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, uint256 qFeeTokenTotalNeeded, 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, uint256 qFeeTokenTotalNeeded, 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, uint256 qFeeTokenTotalNeeded, 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            uint256 qFeeTokenTotalNeeded,\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 qTPRedeemed,\n            uint256 qFeeTokenTotalNeeded,\n            FeeCalcs memory feeCalcs\n        )\n    {\n        (qACtoRedeemTC, qACtoRedeemTP, qACtoReceive, qTPRedeemed, qFeeTokenTotalNeeded, feeCalcs) = _redeemTCandTPto(\n            params_\n        );\n        // return the unused locked TPs\n        unchecked {\n            uint256 qTPDif = params_.qTP - qTPRedeemed;\n            SafeERC20Upgradeable.safeTransfer(IERC20Upgradeable(params_.tp), params_.sender, qTPDif);\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    )\n        external\n        onlyMocQueue\n        returns (uint256 qACSurcharges, uint256 qTPMinted, uint256 qFeeTokenTotalNeeded, FeeCalcs memory feeCalcs)\n    {\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    )\n        external\n        onlyMocQueue\n        returns (uint256 qACSurcharges, uint256 qTCMinted, uint256 qFeeTokenTotalNeeded, FeeCalcs memory feeCalcs)\n    {\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    )\n        external\n        onlyMocQueue\n        returns (uint256 qACSurcharges, uint256 qTPMinted, uint256 qFeeTokenTotalNeeded, FeeCalcs memory feeCalcs)\n    {\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":"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    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    }\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\";\n\n/**\n  @title MocRif\n  @notice A mocCore implementation using RIF as Collateral \n */\ncontract MocRif is MocCARC20 {\n    /**\n     * @notice One time only specific function to migrate block numbers to timestamps\n     * @param nextEmaCalculation_ The next time the EMA will be calculated\n     * @param nextTCInterestPayment_ The next time the TC interest will be paid\n     * @param nextSettlementTime_ The next time the settlement will be performed\n     * @param lastOperationTimeStamp_ The last time the operation was performed\n     */\n    function migrateTimestamps(\n        uint256 nextEmaCalculation_,\n        uint256 nextTCInterestPayment_,\n        uint256 nextSettlementTime_,\n        uint256 lastOperationTimeStamp_\n    ) external onlyAuthorizedChanger {\n        nextEmaCalculation = nextEmaCalculation_;\n        nextTCInterestPayment = nextTCInterestPayment_;\n        nextSettlementTime = nextSettlementTime_;\n        lastOperationTimeStamp = lastOperationTimeStamp_;\n    }\n}\n"},{"file_path":"npm/moc-main-latest@1.0.13/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/@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/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/moc-main-latest@1.0.13/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/@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/moc-main-latest@1.0.13/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/moc-main-latest@1.0.13/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 qFeeTokenTotalNeeded amount of Fee Token used by `sender_` to pay fees. 0 if qAC is used instead\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function _mintTCto(\n        MintTCParams memory params_\n    )\n        internal\n        notLiquidated\n        notPaused\n        returns (uint256 qACtotalNeeded, uint256 qFeeTokenTotalNeeded, FeeCalcs memory feeCalcs)\n    {\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, qFeeTokenTotalNeeded, feeCalcs) = _calcFees(\n            params_.sender,\n            params_.vendor,\n            qACNeededToMint,\n            tcMintFee\n        );\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 qFeeTokenTotalNeeded amount of Fee Token used by `sender_` to pay fees. 0 if qAC is used instead\n     * @return feeCalcs platform fee detail breakdown\n     */\n\n    function _redeemTCto(\n        RedeemTCParams memory params_\n    )\n        internal\n        notLiquidated\n        notPaused\n        returns (uint256 qACtoRedeem, uint256 qFeeTokenTotalNeeded, FeeCalcs memory feeCalcs)\n    {\n        // emas are updated here\n        (\n            uint256 combinedCglb,\n            uint256 combinedCtargemaCA,\n            uint256 tcAvailableToRedeem,\n            uint256[] memory pACtps\n        ) = _getMocMultiCollateralGuard().getCombinedAndTC(address(this));\n        // evaluates whether or not the system coverage is healthy enough to redeem TC\n        // evaluating the multi collateral status, reverts if it's not\n        _evalCombinedCoverage(combinedCglb, combinedCtargemaCA);\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, qFeeTokenTotalNeeded, feeCalcs) = _calcFees(\n            params_.sender,\n            params_.vendor,\n            qACtotalToRedeem,\n            tcRedeemFee\n        );\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 qFeeTokenTotalNeeded amount of Fee Token used by `sender_` to pay fees. 0 if qAC is used instead\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function _mintTPto(\n        MintTPParams memory params_\n    )\n        internal\n        notLiquidated\n        notPaused\n        returns (uint256 qACtotalNeeded, uint256 qFeeTokenTotalNeeded, FeeCalcs memory feeCalcs)\n    {\n        // emas are updated here\n        (\n            uint256 combinedCglb,\n            uint256 combinedCtargemaCA,\n            uint256 tpAvailableToMint,\n            uint256[] memory pACtps\n        ) = _getMocMultiCollateralGuard().getCombinedAndTP(address(this), params_.tp);\n        // evaluates whether or not the system coverage is healthy enough to mint TP\n        // evaluating the multi collateral status, reverts if it's not\n        _evalCombinedCoverage(combinedCglb, combinedCtargemaCA);\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, qFeeTokenTotalNeeded, feeCalcs) = _calcFees(\n            params_.sender,\n            params_.vendor,\n            qACNeededtoMint,\n            tpMintFees[params_.tp]\n        );\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 qFeeTokenTotalNeeded amount of Fee Token used by `sender_` to pay fees. 0 if qAC is used instead\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function _redeemTPto(\n        RedeemTPParams memory params_\n    )\n        internal\n        notLiquidated\n        notPaused\n        returns (uint256 qACtoRedeem, uint256 qFeeTokenTotalNeeded, FeeCalcs memory feeCalcs)\n    {\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, qFeeTokenTotalNeeded, 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 qFeeTokenTotalNeeded amount of Fee Token used by `sender_` to pay fees. 0 if qAC is used instead\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            uint256 qFeeTokenTotalNeeded,\n            FeeCalcs memory feeCalcs\n        )\n    {\n        bytes memory payload = abi.encodeCall(MocCoreExpansion(mocCoreExpansion).mintTCandTPto, (params_));\n        (qACtoMintTC, qACtoMintTP, qACtoSpent, qTCtoMint, qFeeTokenTotalNeeded, feeCalcs) = abi.decode(\n            Address.functionDelegateCall(mocCoreExpansion, payload),\n            (uint256, 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 qTP sent are insufficient.\n     * @param params_ redeem TC and TP function parameters\n     * @dev\n     *      i_ Pegged Token index\n     *      qTC_ amount of Collateral Token to redeem\n     *      qTP_ maximum 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 qTPtoRedeem amount of Pegged Token redeemed\n     * @return qFeeTokenTotalNeeded amount of Fee Token used by `sender_` to pay fees. 0 if qAC is used instead\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 qTPtoRedeem,\n            uint256 qFeeTokenTotalNeeded,\n            FeeCalcs memory feeCalcs\n        )\n    {\n        bytes memory payload = abi.encodeCall(MocCoreExpansion(mocCoreExpansion).redeemTCandTPto, (params_));\n        (qACtoRedeemTC, qACtoRedeemTP, qACtoReceive, qTPtoRedeem, qFeeTokenTotalNeeded, feeCalcs) = abi.decode(\n            Address.functionDelegateCall(mocCoreExpansion, payload),\n            (uint256, 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 qACSurcharges amount of AC used to pay fees and markup\n     * @return qTPMinted amount of Pegged Token minted\n     * @return qFeeTokenTotalNeeded amount of Fee Token used by `sender_` to pay fees. 0 if qAC is used instead\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function _swapTPforTPto(\n        SwapTPforTPParams memory params_\n    )\n        internal\n        notLiquidated\n        notPaused\n        returns (uint256 qACSurcharges, uint256 qTPMinted, uint256 qFeeTokenTotalNeeded, FeeCalcs memory feeCalcs)\n    {\n        bytes memory payload = abi.encodeCall(MocCoreExpansion(mocCoreExpansion).swapTPforTPto, (params_));\n        (qACSurcharges, qTPMinted, qFeeTokenTotalNeeded, feeCalcs) = abi.decode(\n            Address.functionDelegateCall(mocCoreExpansion, payload),\n            (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 - 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 qACSurcharges amount of AC used to pay fees and markup\n     * @return qTCMinted amount of TC minted\n     * @return qFeeTokenTotalNeeded amount of Fee Token used by `sender_` to pay fees. 0 if qAC is used instead\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function _swapTPforTCto(\n        SwapTPforTCParams memory params_\n    )\n        internal\n        notLiquidated\n        notPaused\n        returns (uint256 qACSurcharges, uint256 qTCMinted, uint256 qFeeTokenTotalNeeded, FeeCalcs memory feeCalcs)\n    {\n        bytes memory payload = abi.encodeCall(MocCoreExpansion(mocCoreExpansion).swapTPforTCto, (params_));\n        (qACSurcharges, qTCMinted, qFeeTokenTotalNeeded, feeCalcs) = abi.decode(\n            Address.functionDelegateCall(mocCoreExpansion, payload),\n            (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 - 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 qACSurcharges amount of AC used to pay fees and markup\n     * @return qTPtoMint amount of Pegged Token minted\n     * @return qFeeTokenTotalNeeded amount of Fee Token used by `sender_` to pay fees. 0 if qAC is used instead\n     * @return feeCalcs platform fee detail breakdown\n     */\n    function _swapTCforTPto(\n        SwapTCforTPParams memory params_\n    )\n        internal\n        notLiquidated\n        notPaused\n        returns (uint256 qACSurcharges, uint256 qTPtoMint, uint256 qFeeTokenTotalNeeded, FeeCalcs memory feeCalcs)\n    {\n        bytes memory payload = abi.encodeCall(MocCoreExpansion(mocCoreExpansion).swapTCforTPto, (params_));\n        (qACSurcharges, qTPtoMint, qFeeTokenTotalNeeded, feeCalcs) = abi.decode(\n            Address.functionDelegateCall(mocCoreExpansion, payload),\n            (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 - 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), 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/@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/@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/moc-main-latest@1.0.13/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        // absolute coinbase execution fee applied on Collateral Tokens mint\n        uint256 tcMintExecCost;\n        // absolute coinbase execution fee applied on Collateral Tokens redeem\n        uint256 tcRedeemExecCost;\n        // absolute coinbase execution fee applied on Pegged Tokens mint\n        uint256 tpMintExecCost;\n        // absolute coinbase execution fee applied on Pegged Tokens redeem\n        uint256 tpRedeemExecCost;\n        // absolute coinbase execution fee applied on swap a Pegged Token for another Pegged Token\n        uint256 swapTPforTPExecCost;\n        // absolute coinbase execution fee applied on swap a Pegged Token for Collateral Token\n        uint256 swapTPforTCExecCost;\n        // absolute coinbase execution fee applied on swap Collateral Token for a Pegged Token\n        uint256 swapTCforTPExecCost;\n        // absolute coinbase execution fee applied on redeem Collateral Token and Pegged Token in one operations\n        uint256 redeemTCandTPExecCost;\n        // absolute coinbase execution fee applied on mint Collateral Token and Pegged Token in one operation\n        uint256 mintTCandTPExecCost;\n    }\n\n    // source for all buckets to determine the overall state of the multi-collateral system\n    MocMultiCollateralGuard public mocMultiCollateralGuard;\n    // OperType => Avg Execution cost per Operation\n    mapping(OperType => uint256) public execCost;\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 Execution Fees absolute values 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    }\n\n    /**\n     * @notice get execution fee for the operation requested\n     * @dev only used for coinbase flavor\n     * @param operType_ operation type registered\n     * @return currentExecFee execution fee required for the operation\n     */\n    function getExecFee(OperType operType_) public view returns (uint256 currentExecFee) {\n        unchecked {\n            currentExecFee = execCost[operType_] * _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 executions fees with absolute values 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[50] private __gap;\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/moc-main-latest@1.0.13/contracts/collateral/rc20/MocCARC20.sol","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"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NotAuthorizedChanger","type":"error"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"NotUniqueRole","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":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","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":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IGovernor","name":"newGovernor_","type":"address"}],"name":"changeGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","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":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address","name":"admin_","type":"address"},{"internalType":"contract IGovernor","name":"governor_","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"transferAllRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":false,"constructor_args":null}